{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "03_convolution-digit-recognizer_full_colab.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "include_colab_link": true
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.6.8"
    },
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/mlelarge/dataflowr/blob/master/CEA_EDF_INRIA/03_convolution_digit_recognizer_full_colab.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CUiFyiXKHovB",
        "colab_type": "text"
      },
      "source": [
        "# Convolutions by examples\n",
        "\n",
        "### Acknowledgement\n",
        "\n",
        "Code from Sections 1 to 3 taken from [fastai: lesson 0](http://course.fast.ai/lessons/lesson0.html)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7v7DN_UKHovE",
        "colab_type": "text"
      },
      "source": [
        "## 1. Preparations"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "eQmaHvupHovF",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "%matplotlib inline\n",
        "import math,sys,os,numpy as np\n",
        "from numpy.linalg import norm\n",
        "from matplotlib import pyplot as plt"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "lkRdumG1HovK",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import torch\n",
        "import torchvision\n",
        "from torchvision import models,transforms,datasets"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3JlQUj5IHovP",
        "colab_type": "text"
      },
      "source": [
        "Download MNIST data on disk and convert it to pytorch compatible formating.\n",
        "\n",
        "```torchvision.datasets``` features support (download, formatting) for a collection of popular datasets. The list of available datasets in ```torchvision``` can be found [here](http://pytorch.org/docs/master/torchvision/datasets.html).\n",
        "\n",
        "Note that the download is performed only once. The function will always check first if the data is already on disk.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Bv9h8isvHovQ",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 332
        },
        "outputId": "84d3321f-c473-47d4-f972-71e2f481499a"
      },
      "source": [
        "root_dir = '/content/data/MNIST/'\n",
        "torchvision.datasets.MNIST(root=root_dir,download=True)"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "\r0it [00:00, ?it/s]"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to /content/data/MNIST/MNIST/raw/train-images-idx3-ubyte.gz\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "9920512it [00:01, 9057548.29it/s]                            \n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "Extracting /content/data/MNIST/MNIST/raw/train-images-idx3-ubyte.gz\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "  0%|          | 0/28881 [00:00<?, ?it/s]"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to /content/data/MNIST/MNIST/raw/train-labels-idx1-ubyte.gz\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "32768it [00:00, 135832.73it/s]           \n",
            "  0%|          | 0/1648877 [00:00<?, ?it/s]"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "Extracting /content/data/MNIST/MNIST/raw/train-labels-idx1-ubyte.gz\n",
            "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to /content/data/MNIST/MNIST/raw/t10k-images-idx3-ubyte.gz\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "1654784it [00:00, 2566279.50it/s]                           \n",
            "0it [00:00, ?it/s]"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "Extracting /content/data/MNIST/MNIST/raw/t10k-images-idx3-ubyte.gz\n",
            "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to /content/data/MNIST/MNIST/raw/t10k-labels-idx1-ubyte.gz\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "8192it [00:00, 51573.93it/s]            "
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "Extracting /content/data/MNIST/MNIST/raw/t10k-labels-idx1-ubyte.gz\n",
            "Processing...\n",
            "Done!\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "Dataset MNIST\n",
              "    Number of datapoints: 60000\n",
              "    Root location: /content/data/MNIST/\n",
              "    Split: Train"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 3
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "XW1c2YmiHovW",
        "colab_type": "text"
      },
      "source": [
        "MNIST datasets consists of small images of hand-written digits. The images are grayscale and have size 28 x 28. There are 60,000 training images and 10,000 testing images."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "p9MA5fqrHovZ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "train_set = torchvision.datasets.MNIST(root=root_dir, train=True, download=True)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yaLXqwxaHovg",
        "colab_type": "text"
      },
      "source": [
        "Define and initialize a data loader for the MNIST data already downloaded on disk."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "uEyTgg0THovj",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "MNIST_dataset = torch.utils.data.DataLoader(train_set, batch_size=1, shuffle=True, num_workers=1)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "f12CxE8XHovo",
        "colab_type": "text"
      },
      "source": [
        "For the current notebook, since we are doing no training, we can format data as _numpy ndarrays_ which are easier to plot in matplotlib. The same operations can be easily performed on _pytorch Tensors_."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_UnuFlpWHovq",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "images = train_set.data.numpy().astype(np.float32)/255\n",
        "labels = train_set.targets.numpy()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "RpkGWiaqHovz",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "a6b22829-3ca4-4ae4-b842-104134de0394"
      },
      "source": [
        "print(images.shape,labels.shape)"
      ],
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "(60000, 28, 28) (60000,)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HYSO4Wc4HowH",
        "colab_type": "text"
      },
      "source": [
        "## 2. Data visualization"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tPtQoS_-HowJ",
        "colab_type": "text"
      },
      "source": [
        "For convenience we define a few functions for formatting and plotting our image data"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "F3lsBB7ZHowK",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# plot multiple images\n",
        "def plots(ims, interp=False, titles=None):\n",
        "    ims=np.array(ims)\n",
        "    mn,mx=ims.min(),ims.max()\n",
        "    f = plt.figure(figsize=(12,24))\n",
        "    for i in range(len(ims)):\n",
        "        sp=f.add_subplot(1, len(ims), i+1)\n",
        "        if not titles is None: sp.set_title(titles[i], fontsize=18)\n",
        "        plt.imshow(ims[i], interpolation=None if interp else 'none', vmin=mn,vmax=mx)\n",
        "\n",
        "# plot a single image\n",
        "def plot(im, interp=False):\n",
        "    f = plt.figure(figsize=(3,6), frameon=True)\n",
        "    plt.imshow(im, interpolation=None if interp else 'none')\n",
        "\n",
        "plt.gray()\n",
        "plt.close()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "vfxlah5eHowW",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "outputId": "7b3d4439-666e-4ed1-d193-054dd9de2dcd"
      },
      "source": [
        "plot(images[5000])"
      ],
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 216x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "VY5890I1Howd",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "6d1e8398-d84d-444b-cbdc-00c9451def6f"
      },
      "source": [
        "labels[5000]"
      ],
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "7"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 16
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OEWipA5iHown",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 183
        },
        "outputId": "f8e14cf1-516e-4fb3-9c70-462bbe91b329"
      },
      "source": [
        "plots(images[5000:5005], titles=labels[5000:5005])"
      ],
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 864x1728 with 5 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ABg2l01JHoyL",
        "colab_type": "text"
      },
      "source": [
        "## 3. Filters and convolutions"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "unXh3clNHoyM",
        "colab_type": "text"
      },
      "source": [
        "Here is a simple 3x3 filter, ie a 3x3 matrix (see [Sobel operator](https://en.wikipedia.org/wiki/Sobel_operator) for more examples)"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OWiIsQ38HoyP",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "outputId": "2ed74b6b-d367-4d0b-89dd-022eb6c902e4"
      },
      "source": [
        "top=[[-1,-1,-1],\n",
        "     [ 1, 1, 1],\n",
        "     [ 0, 0, 0]]\n",
        "\n",
        "plot(top)"
      ],
      "execution_count": 18,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 216x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "p3TmBjakHoye",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "cross = np.zeros((28,28))\n",
        "cross += np.eye(28)\n",
        "for i in range(4):\n",
        "    cross[12+i,:] = np.ones(28)\n",
        "    cross[:,12+i] = np.ones(28)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jipouDFOHoyn",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "outputId": "3d5e0f62-522e-4436-b45f-e5c68658423b"
      },
      "source": [
        "plot(cross)"
      ],
      "execution_count": 20,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 216x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "g0j7I3OKHoyt",
        "colab_type": "text"
      },
      "source": [
        "In some fields, convolution or filtering can be better understood as _correlations_. \n",
        "In practice we slide the filter matrix over the image (a bigger matrix) always selecting patches from the image with the same size as the filter. We compute the dot product between the filter and the image patch and store the scalar response which reflects the degree of similarity/correlation between the filter and image patch."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "iiqsEThMHoyu",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from scipy.ndimage.filters import convolve, correlate\n",
        "\n",
        "corr_cross = correlate(cross,top)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zXc6nlfYHoyx",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "outputId": "2b59d15e-aac5-41f6-f9f7-660a9dd87ca9"
      },
      "source": [
        "plot(corr_cross)"
      ],
      "execution_count": 22,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nYII=\n",
            "text/plain": [
              "<Figure size 216x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5mi2j-hFHoy3",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "?correlate"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bPAEi-4gHoy-",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "outputId": "35fb0606-4ed3-434b-a83c-7ae63338d75e"
      },
      "source": [
        "# to see the role of padding\n",
        "corr_cross = correlate(cross,top, mode='constant')\n",
        "plot(corr_cross)"
      ],
      "execution_count": 24,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 216x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "iSTy0Ka1HozC",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "outputId": "f9e1e7da-96af-45c6-af3f-6e0e728da69d"
      },
      "source": [
        "corrtop = correlate(images[5000], top)\n",
        "plot(corrtop)"
      ],
      "execution_count": 25,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 216x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6kp8ArumHozJ",
        "colab_type": "text"
      },
      "source": [
        "By rotating the filter with 90 degrees and calling the ```convolve``` function we get the same response as with the previously called ```correlate``` function."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "K2m8hh6XHozL",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 69
        },
        "outputId": "3911ab52-e03f-4ab3-a141-1c9cff3b5b25"
      },
      "source": [
        "np.rot90(top, 1)"
      ],
      "execution_count": 26,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[-1,  1,  0],\n",
              "       [-1,  1,  0],\n",
              "       [-1,  1,  0]])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 26
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "scrolled": true,
        "id": "MBratD5iHozV",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 236
        },
        "outputId": "796c04dc-823a-4455-d307-936273e1f91b"
      },
      "source": [
        "convtop = convolve(images[5000], np.rot90(top,2))\n",
        "plot(convtop)\n",
        "np.allclose(convtop, corrtop)"
      ],
      "execution_count": 27,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "True"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 27
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 216x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "XqFCxFXoHozd",
        "colab_type": "text"
      },
      "source": [
        "Let's generate a few more variants of our simple 3x3 filter"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "A48nt8YqHoze",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 197
        },
        "outputId": "cc3b26c7-8588-4826-ecb6-0e264aecda6b"
      },
      "source": [
        "straights=[np.rot90(top,i) for i in range(4)]\n",
        "plots(straights)"
      ],
      "execution_count": 28,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nnRuWIbuMSnYZkdyyF8zxqRqvTfLjSf6hqh5d7PuVJDcnSXe/L8mbk7y1qi4k+bckd/WcL67euftW\nvYAljb7+ZLX3YdTs+r6v3qrXL7urM/p98Ji7M77vq7cW92HWNwcCAMBe5cyBAAAwgeIMAAAT7Mvi\nXFVvqKonqupMVb1z1evZrqq6v6q+VFWfXfVadmLKaVfZmuyuluzunOyuluzujNyu1jrmdt+9xrmq\nrknyuSSvz8UPWH8oyd1bnPJzbVXVDyR5IckHu/vVq17PdlXV9Umu33ja1SQ/MtL3YBVkd/Vkd2dk\nd/Vkd/vkdvXWMbf78Rnn25Kc6e7Pd/fXknw4yZ0rXtO2dPenkzy76nXslNOu7pjsrpjs7pjsrpjs\n7ojcrtg65nY/FucbkpzdsH0uHjxWpi6edvU1ST6z2pUMQXbXiOxui+yuEdmdTG7XyLrkdj8WZ9bE\n4rSrH03yju5+ftXrgalkl1HJLiNap9zux+L8ZJKbNmzfuNjHLrrSaVfZkuyuAdndEdldA7K7bXK7\nBtYtt/uxOD+U5JaqemVVvSjJXUlOrnhN+8qU066yJdldMdndMdldMdndEbldsXXM7b4rzt19Icnb\nknw8F19k/ofdfXq1q9qeqvpQkr9J8qqqOldVP73qNW3T/5x29Qer6tHF5Y5VL2rdye5akN0dkN21\nILvbJLdrYe1yu+8+jg4AAHZi3z3jDAAAO6E4AwDABIozAABMoDgDAMAEijMAAEygOAMAwASKMwAA\nTPDf0KgBJ+Hd884AAAAASUVORK5CYII=\n",
            "text/plain": [
              "<Figure size 864x1728 with 4 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "cv5eeO7gHozn",
        "colab_type": "text"
      },
      "source": [
        "We proceed similarly to generate a set of filters with a different behavior"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "xhJFADUoHozr",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 197
        },
        "outputId": "d46adcd7-03a2-4462-c9dd-1b61aefea428"
      },
      "source": [
        "br=[[ 0, 0, 1],\n",
        "    [ 0, 1,-1.5],\n",
        "    [ 1,-1.5, 0]]\n",
        "\n",
        "diags = [np.rot90(br,i) for i in range(4)]\n",
        "plots(diags)"
      ],
      "execution_count": 29,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nZhr9Pjjm7o/f+/ptRnaXKs5VdSTJf0nyr7v7d3Zd97eT/L/uPl9V70ry77r7jkU2nqGqTnf31rrn\n2K/R50824z6Mlt1N+Hc21+j3YVPml92DN/p92IT5R8vtaq61/3ubY/T5k825D4t8qkZV3ZCL/4f4\nW7sfBEnS3S939/nV6QeT3FBVNy2xN8whu4xKdhmR3DK6JT5Vo5J8IsmT3f3Ll1jz+tW6VNVdq31f\nmLs3zCG7jEp2GZHcchgs8akab0vyw0m+VFWPrS77hSTHk6S7P5bk3Ul+sqouJPnrJPf1ki+u3r+T\n6x5gptHnT9Z7H0bNrt/7+q17ftldn9Hvg2Pu/vi9r99G3IdF3xwIAACHlW8OBACACRRnAACY4Jos\nzlX1jqp6qqrOVNUH1j3Plaqq+6vq61X15XXPsh9TvnaVvcnuesnu/snuesnu/sjtem1ibq+51zhX\n1XVJ/jTJ23PxA9YfTvKePb7yc2NV1fcnOZ/kk939lnXPc6Wq6uYkN+/82tUk/2yk38E6yO76ye7+\nyO76ye6Vk9v128TcXovPON+V5Ex3f6W7v5nk00nuXfNMV6S7v5DkxXXPsV++dnXfZHfNZHffZHfN\nZHdf5HbNNjG312JxviXJMzvOn42Dx9rUxa9dfWuSL653kiHI7gaR3SsiuxtEdieT2w2yKbm9Fosz\nG2L1taufSfIz3f3yuueBqWSXUckuI9qk3F6LxfnZJLftOH/r6jIO0Ct97Sp7kt0NILv7IrsbQHav\nmNxugE3L7bVYnB9OckdVvbGqXpXkviSn1jzTNWXK166yJ9ldM9ndN9ldM9ndF7lds03M7TVXnLv7\nQpL3JflsLr7I/D929+PrnerKVNWnkvz3JG+qqrNV9ePrnukK/c3Xrv7Tqnps9fOudQ+16WR3I8ju\nPsjuRpDdKyS3G2HjcnvNfRwdAADsxzX3jDMAAOyH4gwAABMozgAAMIHiDAAAEyjOAAAwgeIMAAAT\nKM4AADDB/wd+MiPuNb91FAAAAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 864x1728 with 4 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zhGJF9gNHoz0",
        "colab_type": "text"
      },
      "source": [
        "We can compose filters to obtain more complex patterns"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "k9ETAdFKHoz1",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 123
        },
        "outputId": "13f71fb7-7477-42d7-b792-b3719cb9b744"
      },
      "source": [
        "rots = straights + diags\n",
        "corrs_cross = [correlate(cross, rot) for rot in rots]\n",
        "plots(corrs_cross)"
      ],
      "execution_count": 30,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5GnSnG1HHoz5",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 123
        },
        "outputId": "c89a8aa9-d43b-4ae5-d914-0dcf61be1f8b"
      },
      "source": [
        "rots = straights + diags\n",
        "corrs = [correlate(images[5000], rot) for rot in rots]\n",
        "plots(corrs)"
      ],
      "execution_count": 31,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n4U1kAgAAAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "plV6mfsjHoz-",
        "colab_type": "text"
      },
      "source": [
        "Next we illustrate the effect of downsampling.\n",
        "We select the most basic downsampling technique: __max pooling__. We keep only the maximum value for sliding windows of size ```7x7```.\n",
        "__Max pooling__ is a handy technique with a few useful perks:\n",
        "- since it selects the maximum values it ensures invariance to translations\n",
        "- reducing the size is helpful since data becomes more compact and easier to compare\n",
        "- we will see later in this course that since max pooling reduces the size of our images, the operations performed later on in the network have bigger receptive field / concern a bigger patch in the input image and allow the discovery of higher level patterns."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QfR3u9FYHo0E",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 123
        },
        "outputId": "badb768d-7c4c-490c-9ec8-7b3f8d839eff"
      },
      "source": [
        "import skimage\n",
        "\n",
        "from skimage.measure import block_reduce\n",
        "\n",
        "def pool(im): return block_reduce(im, (7,7), np.max)\n",
        "\n",
        "plots([pool(im) for im in corrs])"
      ],
      "execution_count": 33,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAABqCAYAAABeQoJYAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAACxdJREFUeJzt3d1rVWcWx/Hf0kQjTVHTtDCYMJm0\ngxJ747T0ptBCLdj0woLezAz0QqVeCYoiFPwXSunNlCIdYSiFMmgv5qK0HUpvBkFqxReiVkyo2lrf\nOsQXNCbimotkSvqac/Zez947j98PHEjS7LXX/p2Hc5a7O/uYuwsAAADI1YK6GwAAAABSYuAFAABA\n1hh4AQAAkDUGXgAAAGSNgRcAAABZY+AFAABA1hh4AQAAkDUGXgAAAGSNgRcAAABZY+AFAABA1jpS\nFDUzPq/4N7i7tbtNVKaLFy+OKKOpqamQOvfv3w+pUyRTibU6lzrXqlmhp/RnFi5cGFLn3r17IXXq\nzDRKR0fMW0dUppKuufuj7W4UlWtXV1dEmbA8clirUe9VUa8jExMTIXVU81qNyvXu3bshdaK0slaT\nDLxorr6+vpA6V69eDalz48aNkDrIT2dnZ0idZcuWhdS5cuVKSJ0c9PT0hNQJzPRcVKEiBgcHQ+pc\nu3YtpE4OazXqvSpqwDt58mRIHdW8VqNyHR0dDalTJS5pAAAAQNYYeAEAAJA1Bl4AAABkraWB18xe\nMrOvzOysmb2euqkHAZmmQa7xyDQNco1HpmmQazwyrd6cA6+ZLZT0N0nDkoYk/cXMhlI3ljMyTYNc\n45FpGuQaj0zTINd4ZFqPVs7wPiPprLuPufukpA8kvZK2reyRaRrkGo9M0yDXeGSaBrnGI9MatDLw\nrpB0Ydb338z87EfMbKuZHTazw1HNZYxM0yDXeGSaxpy5kmnbWKtpsFbjsVZrEHYfXnffK2mv1Lyb\npM9XZJoGucYj03hkmga5xiPTNMg1VitneL+V1D/r+76Zn6E4Mk2DXOORaRrkGo9M0yDXeGRag1YG\n3i8k/dHM/mBmiyT9WdK/0raVPTJNg1zjkWka5BqPTNMg13hkWoM5L2lw93tmtk3SJ5IWStrn7iPJ\nO8sYmaZBrvHINA1yjUemaZBrPDKtR0vX8Lr7R5I+StzLA4VM0yDXeGSaBrnGI9M0yDUemVaPT1oD\nAABA1hh4AQAAkDUGXgAAAGQt7D68sz311FM6fLg590keGxsLqbN+/frSNUZHRwtt19/fr927d5fe\n/9tvv126hiS99dZbIXU2b94cUqeo1atX68CBA7X2MNu5c+dC6qxbty6kThFdXV0aGBgoXefWrVvl\nm5F04sSJkDqPP/546RrXr18vtN0jjzwS8vrT3d1duoYkHTt2LKTOc889F1Jn//79hbZbvny5Xnzx\nxZAeImzatCmkzr59+0rX+Oyzzwpt19vbqw0bNpTef09PT+kakjQ1NRVSJ+r16Pz584W26+np0fDw\ncOn93759u3QNKW6WqPK9ijO8AAAAyBoDLwAAALLGwAsAAICsMfACAAAgawy8AAAAyBoDLwAAALLG\nwAsAAICsMfACAAAgawy8AAAAyBoDLwAAALLGwAsAAICsMfACAAAgawy8AAAAyBoDLwAAALLGwAsA\nAICsMfACAAAgawy8AAAAyFpHiqLnz5/Xtm3bStd57bXXArqRVq1aFVKnv7+/dI0LFy4U2m5iYkJn\nzpwpvf+1a9eWriFJQ0NDIXXqdvnyZb355pul62zdujWgG2lwcDCkzsqVK0vX+PrrrwttNzExodOn\nT5fe//DwcOkaknTlypWQOu+9917pGtu3by+03Z07d3T8+PHS+9+xY0fpGpK0fPnykDrff/99SJ2i\nJicndfHixdJ1HnvssYBupE8//TSkzvPPP1+6xqFDhwptNzU1pcuXL5fe/5o1a0rXiBTx/i9Nz0dF\nmJk6OztL73/p0qWla0gKmUckqbe3t3SN8fHxln6PM7wAAADIGgMvAAAAssbACwAAgKwx8AIAACBr\ncw68ZtZvZp+b2UkzGzGzYn91gR+QaRrkGo9M0yDXeGSaBrnGI9N6tHKXhnuSdrn7ETN7WNKXZvZv\ndz+ZuLeckWka5BqPTNMg13hkmga5xiPTGsx5htfdv3P3IzNf35R0StKK1I3ljEzTINd4ZJoGucYj\n0zTINR6Z1qOta3jNbEDSGknFbtCHnyHTNMg1HpmmQa7xyDQNco1HptVp+YMnzKxb0gFJO9z9xi/8\n962StkpSd3d3WIM5I9M0yDVeO5midb+V6+xMFy1aVEN381M7a3Xx4sUVdzd/tbpWlyxZUkN381M7\na/Whhx6quLv8tHSG18w6Nf2kvO/uH/7S77j7Xnd/2t2fZsHPjUzTaDfXrq6uahuch9rNtNru5q+5\ncp2daUdHkg/FzE67a5VcW9POWuUfZ63hvap6rdylwST9XdIpdy//Gawg00TINR6ZpkGu8cg0DXKN\nR6b1aOUM77OSXpX0gpkdnXm8nLiv3JFpGuQaj0zTINd4ZJoGucYj0xrM+f9z3P0/kqyCXh4YZJoG\nucYj0zTINR6ZpkGu8ci0HnzSGgAAALLGwAsAAICsMfACAAAgawy8AAAAyJq5e3xRs5Ci03fuKG/X\nrl0hdd54442QOu7e9oEtWLDAOzs7S+97YGCgdA1J+vjjj0PqDA4OhtQpkqnUvLX6zjvvhNTZs2dP\n6Rrj4+Oamppq+8CiMn3yyScjymjnzp0hdTZv3hxSp8haXbJkiT/xxBOl9z0yMlK6hiS9++67IXW2\nbNkSUkfSl0XuAd20tRr1+jw+Pl66xtGjR3Xz5s2212pXV5f39fWV3v/Y2FjpGpK0f//+kDobN24M\nqaNM1urq1atD6hw8eLB0jUuXLmlycnLOtcoZXgAAAGSNgRcAAABZY+AFAABA1hh4AQAAkDUGXgAA\nAGSNgRcAAABZY+AFAABA1hh4AQAAkDUGXgAAAGSNgRcAAABZY+AFAABA1hh4AQAAkDUGXgAAAGSN\ngRcAAABZY+AFAABA1hh4AQAAkDUGXgAAAGTN3D2+qNlVSed+41d6JV0L33FxVfbze3d/tN2NWshU\nenBzLZSpxFqdA2s1HpmmQa7xyDSNByXXxmWaZOCdc6dmh9396cp3/Cua1k9RTTuOpvVTRNOOoWn9\nFNW042haP0U07Ria1k9RTTuOpvVTRNOOoWn9FNWk42hSL//HJQ0AAADIGgMvAAAAslbXwLu3pv3+\nmqb1U1TTjqNp/RTRtGNoWj9FNe04mtZPEU07hqb1U1TTjqNp/RTRtGNoWj9FNek4mtSLpJqu4QUA\nAACqwiUNAAAAyFrlA6+ZvWRmX5nZWTN7ver9/6SXfjP73MxOmtmImW2vs5+iyDQNco1HpmmQazwy\nTYNc45Fpi9y9soekhZJGJQ1KWiTpmKShKnv4ST+/k/Snma8flnSmzn7ItDkPciXT+fIgVzKdLw9y\nJdM6H1Wf4X1G0ll3H3P3SUkfSHql4h5+4O7fufuRma9vSjolaUVd/RREpmmQazwyTYNc45FpGuQa\nj0xbVPXAu0LShVnff6OGBGFmA5LWSDpUbydtI9M0yDUemaZBrvHINA1yjUemLeKP1iSZWbekA5J2\nuPuNuvvJAZmmQa7xyDQNco1HpmmQa7wmZlr1wPutpP5Z3/fN/Kw2Ztap6SflfXf/sM5eCiLTNMg1\nHpmmQa7xyDQNco1Hpi2q9D68Ztah6QuY12r6CflC0l/dfaSyJn7cj0n6h6T/uvuOOnooi0zTINd4\nZJoGucYj0zTINR6Ztq7SM7zufk/SNkmfaPpC5n/W9aTMeFbSq5JeMLOjM4+Xa+ynbWSaBrnGI9M0\nyDUemaZBrvHItHV80hoAAACyxh+tAQAAIGsMvAAAAMgaAy8AAACyxsALAACArDHwAgAAIGsMvAAA\nAMgaAy8AAACyxsALAACArP0PuMlGRP1dC7cAAAAASUVORK5CYII=\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MY6Yw-XQHo0P",
        "colab_type": "text"
      },
      "source": [
        "## 4. A simple classifier"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "GK6uj_26Ho0R",
        "colab_type": "text"
      },
      "source": [
        "In this section we will construct a basic classifier similar to k-nearest neighbors.\n",
        "Our classifier will tell us whether a given image depicts a _one_ or an _eight_.\n",
        "\n",
        "To this end we select a set of training images depicting _eights_ and _ones_, we convolve them with our set of filters, pool them and average them for each class and filter. We will thus obtain a set of _representative_ signatures for _eights_ and for _ones_. \n",
        "Given a new test image we compute its features by convolution and pooling with the same filters and then compare them with the _representative_ features. The class with the most _similar_ features is chosen as prediction."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jyc9VagHHo0S",
        "colab_type": "text"
      },
      "source": [
        "We fetch all images from the _eight_ class and from the _one_ class."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ogJld-3qJDpW",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "n=len(images)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Itlgssc9Ho0U",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "eights=[images[i] for i in range(n) if labels[i]==8]\n",
        "ones=[images[i] for i in range(n) if labels[i]==1]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "RGY2P44IHo0X",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "d3ce1414-a951-48d2-c0bc-d141aa97c9e6"
      },
      "source": [
        "len(eights), len(ones)"
      ],
      "execution_count": 39,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(5851, 6742)"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 39
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "CFmNNrKAHo0f",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 317
        },
        "outputId": "d6eef5e4-5384-42c6-dcdc-0db285bb6eb8"
      },
      "source": [
        "plots(eights[:5])\n",
        "plots(ones[:5])"
      ],
      "execution_count": 40,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 864x1728 with 5 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nxhoj2qwsW7bMq5NvoIMn2pxI0unTp7365MmTXp38YJ7Ro0fXvKcMizornVV6E26fPn3q1EkmkZNu\nGDdunFdXypYkrVmzxquz8Ia5ngq5tNprkt6TdKWZHTGzeeoI11QzOyhpSqlG5MgKQpAThCIrCEFO\nUK2KZ4adc78/x4+yd60vNBRZQQhyglBkBSHICarFJ9ABAAAgWlVfTQJSU1OTV2/cuLFb+69cubLL\ntm3btlXTEjKoVy//357JteOIV/J9A++8845Xt7S01LMdAAX3zDPPeLWZ/9kUyTXDW7du7fIYyffF\n5BlnhgEAABAthmEAAABEi2EYAAAA0WLNcAqmTZvm1ddcc03Z+yfX3qxYsSL1npA9yTXCIddxBACg\nWqtXr/bq22+/3auTfx/t2rXLq++8884uj3nq1KmUums8zgwDAAAgWgzDAAAAiBbDMAAAAKLFmuEe\nSK61efLJ8p/y+O6773r17NmzvfrkyZPpNAYgCkOGDGl0C8iASteGRbxuuOEGr07OLcOGDSu7/9q1\na736xIkT6TSWUZwZBgAAQLQYhgEAABAthmEAAABEizXDAZqamrx648aN3dr/s88+8+r29vZqWwIQ\nsRkzZjS6BWQAa4RxLnPnzvXq4cOHl73/vn37vHrTpk2p95RlnBkGAABAtBiGAQAAEC2GYQAAAESL\nNcMBFi9e7NVnzpzp1v6VrkOMOPTq5f/bs1KObr75Zq9etWpV6j0hm7Zt2+bVLS0tDeoEebZr165G\nt4A6aW1t9ep58+Z5daX15VOnTvXqL774Ip3GcoIzwwAAAIgWwzAAAACixTAMAACAaLFmOGH8+PFd\ntt16663deozk9fkOHDhQVU8ohuQa4UpruO644w6vbm5u7nKfvXv3Vt8YMufw4cNlf967d2+vHjVq\nlFe3tbWl3hPy59ChQ41uATUwcuTILtuSa4ST71H56aefvHrdunVeHdsa4STODAMAACBaDMMAAACI\nFsMwAAAAosUwDAAAgGjxBrqEt956q8u2QYMGld3n/fff9+o5c+ak2RIK4oUXXvDqu+++u1v7z58/\nv8u25IXWUQynT58u+3Mz8+rzzz+/lu0AaKDLL7/cqzdv3tzlPldeeWXZx3j22We9OvlhYrHjzDAA\nAACixTAMAACAaDEMAwAAIFqsGU4YMmRIl23JD0tIWrNmjVd/8803qfaEYti/f3+jW0BOJD+4J5md\n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\n",
            "text/plain": [
              "<Figure size 864x1728 with 5 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3Mxs-x1pHo0l",
        "colab_type": "text"
      },
      "source": [
        "We keep the first 1000 digits for the test set."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MEA8brOGHo0n",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "raws8 =  np.mean(eights[1000:],axis=0)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "H-IBmFQOHo01",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "outputId": "08214c2a-8892-41d9-9671-abb044357d64"
      },
      "source": [
        "plot(raws8)"
      ],
      "execution_count": 42,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 216x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Aa3a1Le2Ho07",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "raws1 =  np.mean(ones[1000:],axis=0)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "NIWCe_GWHo1A",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "outputId": "441f2c88-b94e-489a-d9b5-0933792d5a30"
      },
      "source": [
        "plot(raws1)"
      ],
      "execution_count": 44,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAM0AAADKCAYAAAAGucTRAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAC+JJREFUeJzt3V+InOUVx/HfySYbzV+Ma9YY0yRI\nbqRQCyKFemGRFutN9CaYi5KCEC8qtOCFwRulUMiF9g+0CLYNpmAVQa3Bi9oQCrY3YhTxb1uDRpNl\ns2tMNP+Mm2xOL/bdsm6fk50zMzsz+873A2Fnzk5mnnfDL+/M2ed9HnN3AWjcom4PAFhoCA2QRGiA\nJEIDJBEaIInQAEmEBkgiNEASoQGSFrfyl83sDkm/kTQg6Q/uvnuOxzP9AD3L3a2Rx1mz02jMbEDS\nfyR9X9JRSa9J2u7u713m7xAa9KxGQ9PK27NbJB1y9w/dfULSM5K2tvB8wILQSmjWSzoy4/7RqvY1\nZrbTzA6a2cEWXgvoGS19pmmEuz8h6QmJt2eoh1bONCOSNsy4f31VA2qtldC8JmmLmW02s0FJ90ja\n155hAb2r6bdn7n7RzO6X9LKmWs573P3dto0M6FFNt5ybejE+06CHdaLlDPQlQgMkERogidAASYQG\nSCI0QBKhAZIIDZBEaICkeZ/ljNaZNfSL6jkfn539wTrfZZxpgCRCAyQRGiCJ0ABJhAZIons2jxYt\nKv+fNDAwUKxfeeWVxfqqVauK9RUrVhTrS5cuLdajbtjFixeL9a+++ipV//LLL4v1c+fOFesXLlwo\n1icnJ4v1XunmcaYBkggNkERogCRCAyQRGiCp1V0DDks6LWlS0kV3v7kdg1poorleUX1wcLBYj7pk\n69f/32q/kqR169YV6ytXrizWo+7T2bNni/XTp08X6ydPnkzVo9e9dOlSqt4r3bN2tJy/5+7H2/A8\nwILA2zMgqdXQuKS/mdnrZraz9AB2DUDdtPr27FZ3HzGztZL2m9m/3P2VmQ9g1wDUTUtnGncfqb6O\nS3pBUxs9AbXW9JnGzJZLWuTup6vbP5D087aNrAayXbXFi8v/HMuWLSvWr7rqqmJ9aGioWI+6T198\n8UWxHjlz5kyxnr1itFe6YVmtvD0blvRC9YNaLOnP7v7XtowK6GGtbLXxoaRvtXEswIJAyxlIIjRA\nEqEBkrhycx61q2uUnau2Zs2aYj2a0xVdQdmuKz2j5+/1OWYRzjRAEqEBkggNkERogCRCAyTRPeuC\nbHdoyZIlxXrUPbvmmmuK9WhdsuPHy9cQRt2waO5ZdAXoxMREsU73DOgThAZIIjRAEqEBkggNkET3\nrAuyc9Ki7lk0x2x4eLhYHx8fL9bPnz9frJ86dapYj9ZDi54nmqsWdc96HWcaIInQAEmEBkgiNEDS\nnKExsz1mNm5m78yorTGz/Wb2QfW1vJYQUEONdM+elPRbSX+aUdsl6YC77zazXdX9B9s/vHrKds+u\nuOKKYv26664r1qPdBKI5ZlGX7LPPPivWo+5Zdo7ZQjXnmaZaZvbErPJWSXur23sl3dXmcQE9q9nP\nNMPuPlrdPqaphQOBvtDyLzfd3S+3sHm1m0BxRwFgIWr2TDNmZuskqfpa/lWzpnYNcPeb+3WXNNRP\ns6HZJ2lHdXuHpBfbMxyg98359szMnpZ0m6QhMzsq6WFJuyU9a2b3SvpY0rb5HGTdZK9MXL16dbG+\nefPmYj2akxZduTk2NlasR3toRnPM6tYli8wZGnffHnzr9jaPBVgQmBEAJBEaIInQAEmEBkjiys15\nlJ1jtmhR+f+waI7Zxo0bi/VoDlg092x0dLRYj+aYZXcZqBvONEASoQGSCA2QRGiAJEIDJNE96yHL\nly8v1rds2VKsR3PMPvnkk1Q9Wg8t2jWgX7pkEc40QBKhAZIIDZBEaIAkQgMk0T3rgsWLyz/2a6+9\ntliPrtCMnufEidkrbk356KOPivVoD81+uRIzizMNkERogCRCAyQRGiCp2V0DHjGzETN7s/pz5/wO\nE+gdze4aIEm/cvdH2z6iGomuxFy5cmWxvmnTpmI9mmMW7WV5+PDhYv3YsWPFer9fiZnV7K4BQN9q\n5TPN/Wb2VvX2jU2d0DeaDc3jkm6QdJOkUUmPRQ80s51mdtDMDjb5WkBPaSo07j7m7pPufknS7yXd\ncpnHsmsAaqWp0Exvs1G5W9I70WOBuml214DbzOwmSS7psKT75nGMPc/MivVor8zh4fLGcRs2bCjW\nozlm0Z6Yhw4dKtbPnj1brCOn2V0D/jgPYwEWBGYEAEmEBkgiNEASoQGSuHIzIeqSLVmypFhftWpV\nsR7tAnD11VcX69H6Y59++mmxPjIyUqxHV2JGxxXV+31OGmcaIInQAEmEBkgiNEASoQGS6J4VRF2j\naA7YsmXLivXoisu1a9cW69FctZMnTxbrR44cKdZPnTpVrEdXkkb16OeQVbduG2caIInQAEmEBkgi\nNEASoQGS+rp7FnWHBgYGivWlS5cW69Ecs6GhoWJ99erVxXo0NyxaryyqR3PVou5fdLzRumqRunXJ\nIpxpgCRCAyQRGiCJ0ABJjewasMHM/m5m75nZu2b206q+xsz2m9kH1VeWpkVfaKR7dlHSA+7+hpmt\nlPS6me2X9GNJB9x9t5ntkrRL0oPzN9T2i+ZcRVdiRnPMom5YVB8cHCzWz507V6yPj48X659//nmx\nPjk5WaxH3bPoeKPuWfT8dM8q7j7q7m9Ut09Lel/SeklbJe2tHrZX0l3zNUigl6Q+05jZJknflvSq\npGF3H62+dUxSedlIoGYa/uWmma2Q9Jykn7n7qZm/GHR3N7PiudnMdkra2epAgV7R0JnGzJZoKjBP\nufvzVXlseiH06mvxjTe7BqBuGumemabWbn7f3X8541v7JO2obu+Q9GL7hwf0nkbenn1X0o8kvW1m\nb1a1hyTtlvSsmd0r6WNJ2+ZniK2LumTRnKts9yyqR1diRnPMoisuo67amTNnivVs9yz6ObTrys26\naWTXgH9Kin56t7d3OEDvY0YAkERogCRCAyQRGiCpL67cjLpAUVct6jJl61GXLOqGRXO3ovGfP3++\nWI+6Z5Fsl6xf5phFONMASYQGSCI0QBKhAZIIDZDUF92zSNQFirpeFy5cKNajbtiJEyeK9WhdsmjO\nWyS6sjJ63Wic0XFlr9Dsl64aZxogidAASYQGSCI0QBKhAZKskx2PaPGNbsnuQZmdexZ1w7JXSkbj\nif7tJiYmivVorlq2e1ZX7t7QJDzONEASoQGSCA2QRGiApFZ2DXjEzEbM7M3qz53zP1yg++bsnlWr\nZ66buWuAphY73ybpjLs/2vCL9Vj3bKGIumr9MterUxrtnjWy7tmopNHq9mkzm941AOhLrewaIEn3\nm9lbZraHTZ3QLxoOzexdAyQ9LukGSTdp6kz0WPD3dprZQTM72IbxAl3X0IyAateAlyS9PGsR9Onv\nb5L0krt/c47n4U14E/hM0xltmxEQ7Rowvc1G5W5J72QHCSxEjXTPbpX0D0lvS5q+pPEhSds19dbM\nJR2WdN+MndGi5+K/RvSsRs80fT1hE5iJCZvAPCE0QBKhAZIIDZBEaIAkQgMkERogidAASYQGSCI0\nQFKndw04Lunj6vZQdb9fcLy9bWOjD+zo3LOvvbDZQXe/uSsv3gUcb33w9gxIIjRAUjdD80QXX7sb\nON6a6NpnGmCh4u0ZkNTx0JjZHWb2bzM7ZGa7Ov36nVAtaTVuZu/MqK0xs/1m9kH1tRZLXl1mBdZa\nHq/U4dCY2YCk30n6oaQbJW03sxs7OYYOeVLSHbNquyQdcPctkg5U9+vgoqQH3P1GSd+R9JPq37Su\nx9vxM80tkg65+4fuPiHpGUlbOzyGeefur0iavS/5Vkl7q9t7NbW074Ln7qPu/kZ1+7Sk6RVYa3m8\nUudDs17SkRn3j6p/lrgdnrFazzFJw90czHyYtQJrbY+XRkAX+FTLslZty8IKrP9Tt+PtdGhGJG2Y\ncf/6qtYPxqYXWKy+jnd5PG1TrcD6nKSn3P35qlzb4+10aF6TtMXMNpvZoKR7JO3r8Bi6ZZ+kHdXt\nHZJe7OJY2iZagVU1PV6pC7/crDZ/+rWkAUl73P0XHR1AB5jZ05Ju09RM3zFJD0v6i6RnJX1DUzO9\nt7n77GbBgnOZFVhfVQ2PV2JGAJBGIwBIIjRAEqEBkggNkERogCRCAyQRGiCJ0ABJ/wULGfZ2cJUK\n+QAAAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 216x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "3ZML33QNHo1G",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# sum of squared errors\n",
        "def sse(a,b): return ((a-b)**2).sum()\n",
        "\n",
        "def is8_raw_n2(im): return 1 if sse(im,raws1) > sse(im,raws8) else 0"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bJCB6UnOHo1M",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "05c8b03b-ae3a-4a59-8aac-df472730163c"
      },
      "source": [
        "[np.array([is8_raw_n2(im) for im in ims]).sum() for ims in [eights[:1000],ones[:1000]]]"
      ],
      "execution_count": 46,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[912, 27]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 46
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FszIlo_kHo1W",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "81c46c8b-410e-4a37-ec4c-1986e8e4a270"
      },
      "source": [
        "[np.array([(1-is8_raw_n2(im)) for im in ims]).sum() for ims in [eights[:1000],ones[:1000]]]"
      ],
      "execution_count": 47,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[88, 973]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 47
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CFUntUqdHo1e",
        "colab_type": "text"
      },
      "source": [
        "![precision recall](https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Precisionrecall.svg/1024px-Precisionrecall.svg.png)"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "aaYe8malHo1f",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 69
        },
        "outputId": "0c637282-ca79-4354-8f84-97ac394f8d71"
      },
      "source": [
        "Precision_8 = 912/(912+27)\n",
        "Recall_8 = 912/1000\n",
        "Precision_1 = 973/(973+88)\n",
        "Recall_1 = 973/1000\n",
        "\n",
        "print('precision 8:', Precision_8, 'recall 8:', Recall_8)\n",
        "print('precision 1:', Precision_1, 'recall 1:', Recall_1)\n",
        "print('accuracy :', (Recall_1+Recall_8)/2)"
      ],
      "execution_count": 48,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "precision 8: 0.9712460063897763 recall 8: 0.912\n",
            "precision 1: 0.9170593779453345 recall 1: 0.973\n",
            "accuracy : 0.9425\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ud1VbsiRHo1s",
        "colab_type": "text"
      },
      "source": [
        "We now build a classifier with convolutions.\n",
        "\n",
        "We keep 1000 images of _eight_ for the test set and use the remaining ones for the training: we convolve them with our bank of filters, perform max pooling on the responses and store them in ```pool8```."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ptgnsYPmHo1u",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "pool8 = [np.array([pool(correlate(im, rot)) for im in eights[1000:]]) for rot in rots]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "UoxKz3LNHo10",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "30245abe-b252-42df-da25-e15eab61fd91"
      },
      "source": [
        "len(pool8), pool8[0].shape"
      ],
      "execution_count": 50,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(8, (4851, 4, 4))"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 50
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hUSDBnm9Ho13",
        "colab_type": "text"
      },
      "source": [
        "We plot the result of the first filter+pooling on the first 5 _eights_ in our set. "
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zlqkFm1RHo14",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 167
        },
        "outputId": "f924b2b8-bedc-4711-c63e-93a0f8228e5a"
      },
      "source": [
        "plots(pool8[0][0:5])"
      ],
      "execution_count": 51,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAACWCAYAAAA8Els6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAADA1JREFUeJzt3V+oXWV6BvDnzUliGxxTsSrRaKdC\nKUrBKuLNgKBlwMaLKQhSC+NNISgMKHijl70Q74oQRAh0MMLQQZm5KGXKMBeBMNCk/kulUcfI4OBf\nZkRkRsEY9etFTiEdktmfOXuvc/a3fz84cPbJznq/tXhY58liZa9qrQUAAEa1bbMXAAAAi6TwAgAw\nNIUXAIChKbwAAAxN4QUAYGgKLwAAQ1N4AQAYmsILAMDQFF4AAIa2fREbrarJH9+2trY29cjceOON\nk888efLkpPM+++yzfP7557WIbW9GTq677rqpR+bSSy+dfOaLL744+cwkH7bWLl/EhjcjK1ddddXU\nI3PllVdOPvPll1+efGZrbZhzyt69e6cemd27d08+88SJE5PPzGDnlGuvvXbqkbn88oUcvj/o/fff\nn3Texx9/nE8//XTmOWUhhXczXHLJJZPPPHbs2OQz9+3bN+m8o0ePLnT7VQv5vXdejz/++KTzkuSe\ne+6ZfObUx3XdrzZj6KI88MADk898+OGHJ5+5a9euyWeO5MEHH5x85l133TX5zBtuuGHymRnsnPLI\nI49MPvP++++ffObUv2effPLJrve5pQEAgKEpvAAADE3hBQBgaAovAABDU3gBABiawgsAwNAUXgAA\nhqbwAgAwNIUXAIChdRXeqrqzqn5RVW9W1fSPCmEpyAm9ZIVeskIPOWGWmYW3qtaSPJnkb5PckOTe\nqtqUZwyydckJvWSFXrJCDzmhR88V3luTvNla+2Vr7fMkP0zyncUuiyUkJ/SSFXrJCj3khJl6Cu/V\nSd4+6/U76z+Ds8kJvWSFXrJCDzlhpu3z2lBV7U+yf17bY0xyQi9ZoYec0EtWVltP4X03yTVnvd67\n/rP/p7V2MMnBJKmqNpfVsUzkhF6yQq+ZWZET4pxCh55bGp5P8hdV9edVtTPJ3yf5t8UuiyUkJ/SS\nFXrJCj3khJlmXuFtrX1RVd9L8tMka0m+31o7sfCVsVTkhF6yQi9ZoYec0KPrHt7W2k+S/GTBa2HJ\nyQm9ZIVeskIPOWEWT1oDAGBoCi8AAENTeAEAGJrCCwDA0BReAACGpvACADA0hRcAgKEpvAAADE3h\nBQBgaF1PWvu6qio7d+5cxKbP64knnph0XpIcOXJk8pknT56cdN6pU6cWtu21tbXs3r17Yds/l127\ndk06L0lef/31yWeyca+88srkMw8dOjT5zJHs2LEjV1xxxaQz19bWJp2XJLfddtvkM0e0fftCKtB5\nffjhh5POS5LHHnts8pnvvffepPNOnz7d9T5XeAEAGJrCCwDA0BReAACGpvACADA0hRcAgKEpvAAA\nDE3hBQBgaAovAABDU3gBABiawgsAwNBmFt6q+n5V/bqq/meKBbG8ZIUeckIvWaGHnNCj5wrv00nu\nXPA6GMPTkRVmezpyQp+nIyvM9nTkhBlmFt7W2pEkH02wFpacrNBDTuglK/SQE3q4hxcAgKFtn9eG\nqmp/kv3z2h5jOjsn27b59xbn55xCj7Nzsra2tsmrYStzTlltcyu8rbWDSQ4mybZt29q8tstYzs7J\n9u3b5YTzOjsrVSUrnNPZOdm5c6eccF7OKavNJTYAAIbW87Fk/5rkP5P8ZVW9U1X/uPhlsYxkhR5y\nQi9ZoYec0GPmLQ2ttXunWAjLT1boISf0khV6yAk93NIAAMDQFF4AAIam8AIAMDSFFwCAoSm8AAAM\nTeEFAGBoCi8AAENTeAEAGJrCCwDA0GY+ae1CtNZy6tSpRWz6vD744INJ5yXJG2+8MfnMt956a/KZ\ni/Lll1/mo48+mnTmgQMHJp2XJHv27Jl85rZt0/9b9quvvpp85iK9/fbbk8989tlnJ585ktOnT+fd\nd9+ddObUv+uSZN++fZPPfOaZZyafuUgXX3xxbr755klnXn/99ZPOS5Ljx49PPvOpp56afGYPV3gB\nABiawgsAwNAUXgAAhqbwAgAwNIUXAIChKbwAAAxN4QUAYGgKLwAAQ1N4AQAYmsILAMDQZhbeqrqm\nqg5X1atVdaKqHpxiYSwXOaGXrNBLVughJ/TY3vGeL5I83Fp7qaq+keTFqvpZa+3VBa+N5SIn9JIV\neskKPeSEmWZe4W2tvd9ae2n9+98leS3J1YteGMtFTuglK/SSFXrICT2+1j28VfXNJDclObaIxTAG\nOaGXrNBLVughJ5xPzy0NSZKqujjJj5I81Fr77Tn+fH+S/XNcG0tITuglK/T6Q1mRE/7P1zmnXHTR\nRROvjs3WdYW3qnbkTIh+0Fr78bne01o72Fq7pbV2yzwXyPKQE3rJCr1mZUVOSL7+OWXHjh3TLpBN\n1/MpDZXkX5K81lr758UviWUkJ/SSFXrJCj3khB49V3i/leS7Se6oquPrX/sWvC6Wj5zQS1boJSv0\nkBNmmnkPb2vt50lqgrWwxOSEXrJCL1mhh5zQw5PWAAAYmsILAMDQFF4AAIam8AIAMDSFFwCAoSm8\nAAAMTeEFAGBoCi8AAENTeAEAGNrMJ60tiwMHDkw+8+677558Jhtz2WWXTT7zvvvum3zmoUOHJp85\nmueee27ymcePH5985uHDhyefOZJHH3108pm333775DNH88knn+TIkSOTztyM8/LRo0cnn7lVucIL\nAMDQFF4AAIam8AIAMDSFFwCAoSm8AAAMTeEFAGBoCi8AAENTeAEAGJrCCwDA0BReAACGNrPwVtUf\nVdV/VdV/V9WJqvqnKRbG8pEVesgJvWSFHnJCj+0d7zmV5I7W2idVtSPJz6vqP1prHtDM75MVesgJ\nvWSFHnLCTDMLb2utJflk/eWO9a+2yEWxnGSFHnJCL1mhh5zQo+se3qpaq6rjSX6d5GettWPneM/+\nqnqhql6Y9yJZHrOyIickzin0c06hh3MKs3QV3tbal621v06yN8mtVfVX53jPwdbaLa21W+a9SJbH\nrKzICYlzCv2cU+jhnMIsX+tTGlprHyc5nOTOxSyHUcgKPeSEXrJCDznhfHo+peHyqvqT9e//OMm3\nk7y+6IWxfGSFHnJCL1mhh5zQo+dTGvYkOVRVazlTkJ9trf37YpfFkpIVesgJvWSFHnLCTD2f0vBK\nkpsmWAtLTlboISf0khV6yAk9PGkNAIChKbwAAAxN4QUAYGgKLwAAQ1N4AQAYmsILAMDQFF4AAIam\n8AIAMDSFFwCAoVVrbf4brfpNkl9dwF/90yQfznk5W9Ey7eeftdYuX8SGN5CTZLmO4YVatn3cillZ\ntmN4oZZpP7diTpLlOoYXatn2cStmZdmO4YVapv3syslCCu+FqqoXWmu3bPY6Fm1V9nORVuEYrsI+\nLtqqHMNV2c9FWoVjuAr7uGircgxH3E+3NAAAMDSFFwCAoW21wntwsxcwkVXZz0VahWO4Cvu4aKty\nDFdlPxdpFY7hKuzjoq3KMRxuP7fUPbwAADBvW+0KLwAAzNWWKbxVdWdV/aKq3qyqRzZ7PfNWVddU\n1eGqerWqTlTVg5u9pmU0ek4SWZmX0bMiJ/Mxek4SWZmX0bMyek62xC0NVbWW5I0k307yTpLnk9zb\nWnt1Uxc2R1W1J8me1tpLVfWNJC8m+buR9nHRViEniazMwypkRU42bhVyksjKPKxCVkbPyVa5wntr\nkjdba79srX2e5IdJvrPJa5qr1tr7rbWX1r//XZLXkly9uataOsPnJJGVORk+K3IyF8PnJJGVORk+\nK6PnZKsU3quTvH3W63cy0EH+fVX1zSQ3JTm2uStZOiuVk0RWNmClsiInF2ylcpLIygasVFZGzMlW\nKbwro6ouTvKjJA+11n672eth65IVesgJvWSFHqPmZKsU3neTXHPW673rPxtKVe3ImRD9oLX2481e\nzxJaiZwksjIHK5EVOdmwlchJIitzsBJZGTknW+U/rW3PmZvB/yZnAvR8kn9orZ3Y1IXNUVVVkkNJ\nPmqtPbTZ61lGq5CTRFbmYRWyIicbtwo5SWRlHlYhK6PnZEtc4W2tfZHke0l+mjM3ST87UojWfSvJ\nd5PcUVXH17/2bfailsmK5CSRlQ1bkazIyQatSE4SWdmwFcnK0DnZEld4AQBgUbbEFV4AAFgUhRcA\ngKEpvAAADE3hBQBgaAovAABDU3gBABiawgsAwNAUXgAAhva/GoY47fnqvYsAAAAASUVORK5CYII=\n",
            "text/plain": [
              "<Figure size 864x1728 with 5 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5i4oiuoeHo17",
        "colab_type": "text"
      },
      "source": [
        "For the 3 first _eightts_ in our set, we plot the result of the 8 filters+pooling"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Av_HAmtJHo17",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 441
        },
        "outputId": "58e7c5bd-5186-46c4-8ef1-6331c3007df8"
      },
      "source": [
        "plots([pool8[i][0] for i in range(8)])\n",
        "plots([pool8[i][1] for i in range(8)])\n",
        "plots([pool8[i][2] for i in range(8)])\n",
        "plots([pool8[i][3] for i in range(8)])"
      ],
      "execution_count": 52,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nfwAP7wJRnW3gZgAAAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nAAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zqDZeWY6Ho1-",
        "colab_type": "text"
      },
      "source": [
        "We normalize the data in order to smoothen activations and bring them to similar ranges of values"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "D5wmCZY9Ho2A",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def normalize(arr): return (arr-arr.mean())/arr.std()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5-bzBjC6Ho2D",
        "colab_type": "text"
      },
      "source": [
        "Next we compute the average _eight_ by averaging all responses for each filter from _rots_."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Ldr9Cpx5Ho2D",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "filts8 = np.array([ims.mean(axis=0) for ims in pool8])\n",
        "filts8 = normalize(filts8)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oZt78eGSHo2H",
        "colab_type": "text"
      },
      "source": [
        "We should obtain a set of canonical _eights_ responses for each filter."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_UdpsK6AHo2K",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 123
        },
        "outputId": "5e641bf5-e5dc-4670-9aa1-bd1a359c9a63"
      },
      "source": [
        "plots(filts8)"
      ],
      "execution_count": 55,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nAAAo2v8ArzqKhiVzN28AAAAASUVORK5CYII=\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4HaAjI_uHo2O",
        "colab_type": "text"
      },
      "source": [
        "We proceed similarly with training samples from the _one_ class and plot the canonical _ones_."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "e6baq8YKHo2P",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "pool1 = [np.array([pool(correlate(im, rot)) for im in ones[1000:]]) for rot in rots]\n",
        "filts1 = np.array([ims.mean(axis=0) for ims in pool1])\n",
        "filts1 = normalize(filts1)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "eq2CtFfAHo2T",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 123
        },
        "outputId": "9741f043-dc2b-440e-de8f-27baa6ba1c7b"
      },
      "source": [
        "plots(filts1)"
      ],
      "execution_count": 57,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAABqCAYAAABeQoJYAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAACoZJREFUeJzt3U+I3Od5B/DnWf2xJSRjbOtgO6Zp\nsYzwTUXEhtxSg9P4EPBBtIZYN58CMRSMzzrJl95yEaTQg0woKIdiB0IP8cGXENmkB9lIuBIiERGu\n3MWRbAlZu28P2hQnTaLZmeed3/jV5wMDu6vd7zy/7/5m99EwO5OttQAAgFGtTT0AAAD0ZOEFAGBo\nFl4AAIZm4QUAYGgWXgAAhmbhBQBgaBZeAACGZuEFAGBoFl4AAIZm4QUAYGg7e4RmZsnrFe/fv78i\nJh577LGSnAsXLiyccfv27djc3Mztft2qdfrII4+U5Fy8eLEkp7W27U4j6nrNnOvq/5+dO2tukrdv\n3144o7U2V69VnVZ1cfDgwZKc8+fPL5yxubk56e2/6jx9+OGHS3LW19dLcjY2Nq621g5s9+uqet2z\nZ09FTDzwwAMlOVevXl04Y+pztarThx56qCTnypUrJTlTn6t79+6tiIm1tZr7S69fv16SM8vvqi4L\nb5UjR46U5Bw/frwk5+jRowtnVPwgWsSzzz5bkvPyyy+X5Bw7dmzhjM3NzYJJFrN79+6SnFVaJG7e\nvFkwyfwefPDBkpxTp06V5Dz33HMLZ3z66acFk8yv6j8RL774YknO6dOnS3I++eSTSyVBc3rqqadK\ncp5//vmSnJMnTy6cce3atYJJ5lfV6UsvvVSSc+LEiZKc9fX1Sc/VQ4cOleRU3Xn27rvvLpyxsbEx\n0+d5SAMAAEOz8AIAMDQLLwAAQ5tp4c3Mb2fmucz8KDNf7z3UvUCnfei1nk770Gs9nfah13o6Xb67\nLryZuSMifhgRfx8RT0fEP2bm070HG5lO+9BrPZ32odd6Ou1Dr/V0Oo1Z7uH9RkR81Fq70Fq7FRE/\njojv9h1reDrtQ6/1dNqHXuvptA+91tPpBGZZeB+PiF9/6f3fbH3sD2TmK5l5JjPPVA03MJ32odd6\nOu3jrr3qdNucq304V+s5VydQ9jy8rbWTEXEyou4Jku91Ou1Dr/V0Wk+nfei1nk770GutWe7hvRwR\nT3zp/a9tfYz56bQPvdbTaR96rafTPvRaT6cTmGXh/WVEHMzMv87M3RHxDxHx733HGp5O+9BrPZ32\nodd6Ou1Dr/V0OoG7PqShtXY7M78fET+LiB0R8S+ttbPdJxuYTvvQaz2d9qHXejrtQ6/1dDqNmR7D\n21r7aUT8tPMs9xSd9qHXejrtQ6/1dNqHXuvpdPm80hoAAEOz8AIAMDQLLwAAQyt7Ht4evvjii5Kc\n48ePl+RcuXJl4YzWpn0qvddfr3nJ7t27d5fkbG5uluRMbd++fSU5Bw8eLMk5c2bx5ynPzIJJ5ld1\nbhw+fLgk59atWwtnTH3737NnT0nOM888U5Lz5ptvluRMbWNjoyTn5s2bJTkV80x9rh49erQk58aN\nGyU56+vrJTlTq7rtnj9/viSnYpeY9XbjHl4AAIZm4QUAYGgWXgAAhmbhBQBgaBZeAACGZuEFAGBo\nFl4AAIZm4QUAYGgWXgAAhmbhBQBgaBZeAACGZuEFAGBoFl4AAIZm4QUAYGgWXgAAhmbhBQBgaBZe\nAACGtrNb8M7Fo3fs2FEwScTFixdLcqZW0ceRI0cKJol47bXXSnJG8eSTT5bkrK3V/B/0888/Xzij\ntVYwyfyOHTtWknPjxo2SnM8++2zhjKk7feGFF0pyNjY2SnIqOl1Uxe+qKlW3/+vXry+csci5WvG7\n6tFHH104IyLijTfeKMnJzJKceXvNzJXaq6puu1U/n2fhHl4AAIZm4QUAYGgWXgAAhmbhBQBgaHdd\neDPzicz8eWZ+kJlnM/MHyxhsZDrtQ6/1dNqHXuvptA+91tPpNGb5k7/bEfFPrbX3M3N/RLyXmf/R\nWvug82wj02kfeq2n0z70Wk+nfei1nk4ncNd7eFtrv22tvb/19rWI+DAiHu892Mh02ode6+m0D73W\n02kfeq2n02ls6zG8mfn1iDgcEb/oMcy9SKd96LWeTvvQaz2d9qHXejpdnpmfxTgz90XE6Yh4tbX2\nuz/x769ExCuFsw1Pp33otZ5O+/hLvep0Ps7VPpyr9ZyryzXTwpuZu+LON+VUa+0nf+pzWmsnI+Lk\n1udP+3JCXwE67UOv9XTax9161en2OVf7cK7W2+65ura2ptcFzfIsDRkRP4qID1tr/9x/pPHptA+9\n1tNpH3qtp9M+9FpPp9OY5TG834yI70XEtzLzV1uX73Sea3Q67UOv9XTah17r6bQPvdbT6QTu+pCG\n1tq7EZFLmOWeodM+9FpPp33otZ5O+9BrPZ1OwyutAQAwNAsvAABDs/ACADA0Cy8AAEOb+YUntiMz\nY21t8V368uXLBdNErK+vl+S0Nt3T4GVm7Nq1a+Gcc+fOFUwT8d5775XkTG1tbS327t27cM6JEycK\npol46623SnLeeeedkpwp3X///SU5Vd+bKWVm3HfffQvnHDp0qGCaiLfffrskZ8qfqb+3ubm5cEbF\n77uIiEuXLpXkTGltba3kXD179mzBNBEff/xxSc4qnKs7duxYOKNij4iIOHDgQEnOnWdoW8ys3xv3\n8AIAMDQLLwAAQ7PwAgAwNAsvAABDs/ACADA0Cy8AAEOz8AIAMDQLLwAAQ7PwAgAwNAsvAABDs/AC\nADA0Cy8AAEOz8AIAMDQLLwAAQ7PwAgAwNAsvAABDs/ACADC0bK3Vh2b+d0Rc+guf8khEXC2/4vkt\nc56/aq0d2O4XzdBpxL3b61ydRjhX78K5Wk+nfei1nk77uFd6XblOuyy8d73SzDOttSNLv+I/Y9Xm\nmdeqHceqzTOPVTuGVZtnXqt2HKs2zzxW7RhWbZ55rdpxrNo881i1Y1i1eea1SsexSrP8noc0AAAw\nNAsvAABDm2rhPTnR9f45qzbPvFbtOFZtnnms2jGs2jzzWrXjWLV55rFqx7Bq88xr1Y5j1eaZx6od\nw6rNM69VOo5VmiUiJnoMLwAALIuHNAAAMLSlL7yZ+e3MPJeZH2Xm68u+/j+a5YnM/HlmfpCZZzPz\nB1POMy+d9qHXejrtQ6/1dNqHXuvpdEattaVdImJHRPxXRPxNROyOiP+MiKeXOcMfzfNoRPzt1tv7\nI+L8lPPodHUuetXpV+WiV51+VS561emUl2Xfw/uNiPiotXahtXYrIn4cEd9d8gz/p7X229ba+1tv\nX4uIDyPi8anmmZNO+9BrPZ32odd6Ou1Dr/V0OqNlL7yPR8Svv/T+b2JFisjMr0fE4Yj4xbSTbJtO\n+9BrPZ32odd6Ou1Dr/V0OiN/tBYRmbkvIk5HxKuttd9NPc8IdNqHXuvptA+91tNpH3qtt4qdLnvh\nvRwRT3zp/a9tfWwymbkr7nxTTrXWfjLlLHPSaR96rafTPvRaT6d96LWeTme01OfhzcydcecBzH8X\nd74hv4yIl1prZ5c2xB/OkxHxrxHxP621V6eYYVE67UOv9XTah17r6bQPvdbT6eyWeg9va+12RHw/\nIn4Wdx7I/G9TfVO2fDMivhcR38rMX21dvjPhPNum0z70Wk+nfei1nk770Gs9nc7OK60BADA0f7QG\nAMDQLLwAAAzNwgsAwNAsvAAADM3CCwDA0Cy8AAAMzcILAMDQLLwAAAztfwGH8gdAnGH9hwAAAABJ\nRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Bu97H3bNHo2Z",
        "colab_type": "text"
      },
      "source": [
        "Do you notice any differences between ```filts8``` and ```filts1```? Which ones?"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Krvaio26Ho2a",
        "colab_type": "text"
      },
      "source": [
        "We define a function that correlates a given image with all filters from ```rots``` and max pools the responses."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "kgnZzimPHo2a",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def pool_corr(im): return np.array([pool(correlate(im, rot)) for rot in rots])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "2vFjsSxcHo2c",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 123
        },
        "outputId": "1286f0a6-6a55-470c-f32f-4780088d8eb8"
      },
      "source": [
        "plots(pool_corr(eights[1000]))"
      ],
      "execution_count": 59,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Td0bFQ04Ho2j",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 140
        },
        "outputId": "17012683-4c25-4e59-bcc6-b8392207448d"
      },
      "source": [
        "#check \n",
        "plots([pool8[i][0] for i in range(8)])\n",
        "np.allclose(pool_corr(eights[1000]),[pool8[i][0] for i in range(8)])"
      ],
      "execution_count": 60,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "True"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 60
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAABqCAYAAABeQoJYAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAACmdJREFUeJzt3d+L3eWdwPHP4+SHaKOCW0GsWBcW\nJCBYWQoSvGkFu70pghe6kDtRhEKFBcmFf4MQcS8MuLhIoRRSUYZA3YtK6IWhaegqRmKyJcX8ECzi\ntAlJxmSeXmS2pFI7Z77n85zv1yevFwwkceZznvOeL5OPh5NzSq01AACgVzeMfQAAAGjJwgsAQNcs\nvAAAdM3CCwBA1yy8AAB0zcILAEDXLLwAAHTNwgsAQNcsvAAAdM3CCwBA17a0GFpKSXm/4qWlpYwx\n8cADD6TMOX78+NwzLly4EKurq2WzX5fV9KabbsoYE1988cWk5tRaN900Iq9rr4Z0nVrTO+64I2XO\n559/PveMy5cvx5UrV772TbPceuutKXNWVlb+WGv95ma/LqvrLbfckjEmtmzJ+St5ZWVl7hlra2ux\ntrY22rWa1SLre3Pp0qWUOefPnx/1Wt2+fXvGmFhdXU2ZU2vOj7ZZ/q5qsvBmyfphePjw4ZQ5jz76\n6Nwz3n333YSTDHffffelzPn0009T5nz88ccpc+CrPPHEEylz3nrrrblnnDlzJuEk48t6MOLhhx9O\nmbO8vPyHlEED7dq1K2XObbfdljLnwIEDc884d+5cwkmGu/3221PmPPLIIylzTpw4kTLn0KFDo16r\n99xzT8qckydPpszJWpxn4SkNAAB0zcILAEDXLLwAAHRtpoW3lPKDUsqxUsqJUsqe1oe6Hmjahq75\nNG1D13yatqFrPk0Xb8OFt5SyFBH/GRH/FhE7I+LJUsrO1gfrmaZt6JpP0zZ0zadpG7rm03QcszzC\n+92IOFFr/X2tdTUifhYRP2p7rO5p2oau+TRtQ9d8mrahaz5NRzDLwntXRFz72lGn1v/sb5RSni6l\nHC6l5LwGWN80bUPXfJq2sWFXTTfNtdqGazWfa3UEaa/DW2vdFxH7Ivp9kfRF07QNXfNpmk/TNnTN\np2kbuuaa5RHe0xFx9zW//9b6nzGcpm3omk/TNnTNp2kbuubTdASzLLy/iYh/KaXcW0rZFhFPRMT8\nbzl0fdO0DV3zadqGrvk0bUPXfJqOYMOnNNRaL5dSfhwRv4yIpYj4r1rrB81P1jFN29A1n6Zt6JpP\n0zZ0zafpOGZ6Dm+t9UBEzP/m3PyVpm3omk/TNnTNp2kbuubTdPG80xoAAF2z8AIA0DULLwAAXUt7\nHd5rlVJi27Ztc8/Zu3dvwmkiDh48mDLno48+mnvGxYsXE04y3Msvv5wy5+jRoylznnrqqZQ5Q2Vd\nq/v27Us4TcSDDz6YMueFF16Ye8Y777wz/0Hm8Prrr496+1+2srIy94zl5eVBX1dKia1bt859+6+8\n8srcMyIiduzYkTLntddeS5kzVFbXZ599NuE0EW+//XbKnCeffHLuGfv37x/0daWU2L59+9y3v2fP\nnrlnROT9TH3sscdS5gyV1fX5559POE3ElStXUua8+OKLc884efLkTJ/nEV4AALpm4QUAoGsWXgAA\numbhBQCgaxZeAAC6ZuEFAKBrFl4AALpm4QUAoGsWXgAAumbhBQCgaxZeAAC6ZuEFAKBrFl4AALpm\n4QUAoGsWXgAAumbhBQCgaxZeAAC6tqXF0FprXLp0ae45n3zyScJpIo4fP54y5+TJkylzxrS0tJQy\n54Yb+vh/paxr9f333084TcSRI0dS5rz55pspc8ZUa02Zs3PnzpQ5u3fvTpkzRK01VldX557zxhtv\nJJwm4plnnkmZs7y8nDJnqKyuZ8+eTThNxIULF1LmvPrqqylzhqi1xsWLF+eek/WzMOvnyGeffZYy\nZ6isrmfOnEk4Td7feceOHUuZM4s+thYAAPgKFl4AALpm4QUAoGsWXgAAurbhwltKubuU8qtSytFS\nygellJ8s4mA907QNXfNp2oau+TRtQ9d8mo5jlldpuBwR/1FrPVJK2RERvy2l/E+t9Wjjs/VM0zZ0\nzadpG7rm07QNXfNpOoINH+GttZ6ttR5Z//WfI+LDiLir9cF6pmkbuubTtA1d82nahq75NB3Hpp7D\nW0r5dkR8JyIOtTjM9UjTNnTNp2kbuubTtA1d82m6ODO/8UQp5RsRsT8inqu1/unv/PenI+LpxLN1\nT9M2dM2naRv/qKumw7hW23Ct5nOtLtZMC28pZWtc/ab8tNb6i7/3ObXWfRGxb/3zc97apGOatqFr\nPk3b2KirppvnWm3DtZrPtbp4s7xKQ4mIVyPiw1rri+2P1D9N29A1n6Zt6JpP0zZ0zafpOGZ5Du+u\niNgdEd8rpfxu/eOHjc/VO03b0DWfpm3omk/TNnTNp+kINnxKQ6311xFRFnCW64ambeiaT9M2dM2n\naRu65tN0HN5pDQCArll4AQDomoUXAICuWXgBAOjazG88MYaXXnopZc7jjz+eMqcHa2trKXPOnz+f\nMqcX9957b8qchx56KGXO3r17U+aM6c4770yZc+DAgZQ5PbjxxhtT5rz33nspc3px8ODBlDn3339/\nypwenDt3LmXO6dOnU+b04tSpUylzbr755pQ5i+QRXgAAumbhBQCgaxZeAAC6ZuEFAKBrFl4AALpm\n4QUAoGsWXgAAumbhBQCgaxZeAAC6ZuEFAKBrFl4AALpm4QUAoGsWXgAAumbhBQCgaxZeAAC6ZuEF\nAKBrFl4AALpWaq35Q0v5NCL+8A8+5Z8i4o/pNzzcIs9zT631m5v9ohmaRly/XQc1jXCtbsC1mk/T\nNnTNp2kb10vXyTVtsvBueKOlHK61/uvCb/grTO08Q03tfkztPENM7T5M7TxDTe1+TO08Q0ztPkzt\nPENN7X5M7TxDTO0+TO08Q03pfkzpLP/PUxoAAOiahRcAgK6NtfDuG+l2v8rUzjPU1O7H1M4zxNTu\nw9TOM9TU7sfUzjPE1O7D1M4z1NTux9TOM8TU7sPUzjPUlO7HlM4SESM9hxcAABbFUxoAAOjawhfe\nUsoPSinHSiknSil7Fn37XzrL3aWUX5VSjpZSPiil/GTM8wylaRu65tO0DV3zadqGrvk0nVGtdWEf\nEbEUEf8XEf8cEdsi4n8jYuciz/Cl89wZEQ+u/3pHRHw05nk0nc6Hrpp+XT501fTr8qGrpmN+LPoR\n3u9GxIla6+9rrasR8bOI+NGCz/BXtdaztdYj67/+c0R8GBF3jXWegTRtQ9d8mrahaz5N29A1n6Yz\nWvTCe1dEfHzN70/FREKUUr4dEd+JiEPjnmTTNG1D13yatqFrPk3b0DWfpjPyj9YiopTyjYjYHxHP\n1Vr/NPZ5eqBpG7rm07QNXfNp2oau+abYdNEL7+mIuPua339r/c9GU0rZGle/KT+ttf5izLMMpGkb\nuubTtA1d82nahq75NJ3RQl+Ht5SyJa4+gfn7cfUb8puI+Pda6wcLO8TfnqdExH9HxGe11ufGOMO8\nNG1D13yatqFrPk3b0DWfprNb6CO8tdbLEfHjiPhlXH0i88/H+qas2xURuyPie6WU361//HDE82ya\npm3omk/TNnTNp2kbuubTdHbeaQ0AgK75R2sAAHTNwgsAQNcsvAAAdM3CCwBA1yy8AAB0zcILAEDX\nLLwAAHTNwgsAQNf+ApmtDWdy8EL6AAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "x2cJdyL2Ho2u",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# function used for a voting based classifier that will indicate which one of the \n",
        "# two classes is most likely given the sse distances\n",
        "# n2 comes from norm2\n",
        "# is8_n2 returns 1 if it thinks it's an eight and 0 otherwise\n",
        "def is8_n2(im): return 1 if sse(pool_corr(im),filts1) > sse(pool_corr(im),filts8) else 0"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SDFMHV3nHo2y",
        "colab_type": "text"
      },
      "source": [
        "We perform a check to see if our function actually works. We correlate the an image of _eight_ with ```filts8``` and ```filts1```. It should give smaller error for the _eights_."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "C_eFq1EWHo2z",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "fa216392-49f9-48f1-8f86-272b9f88d4d5"
      },
      "source": [
        "sse(pool_corr(eights[0]), filts8), sse(pool_corr(eights[0]), filts1)"
      ],
      "execution_count": 62,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(103.67323, 126.09805)"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 62
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "yNINKzvKHo24",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "outputId": "993139f8-5c47-4103-bbf2-0e452504a636"
      },
      "source": [
        "plot(eights[0])"
      ],
      "execution_count": 63,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 216x432 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "roCmorVtHo29",
        "colab_type": "text"
      },
      "source": [
        "We now test our classifier on the 1000 images of _eights_ and 1000 images of _ones_"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "qyn22NsLHo2-",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "23a4f121-b368-4936-b492-b6d52c9401a1"
      },
      "source": [
        "[np.array([is8_n2(im) for im in ims]).sum() for ims in [eights[:1000],ones[:1000]]]"
      ],
      "execution_count": 64,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[969, 37]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 64
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qMNwT2BFHo3G",
        "colab_type": "text"
      },
      "source": [
        "It said in 969 cases it is an _eight_ and 37 case it is a _one_"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OQa5eFzLHo3J",
        "colab_type": "text"
      },
      "source": [
        "Let's now test the opposite, ie it's not an _eight_ , it's not a _one_"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "TEPN_aPbHo3K",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "2da95bd6-8c28-41c9-95a7-49bc983f2d55"
      },
      "source": [
        "[np.array([(1-is8_n2(im)) for im in ims]).sum() for ims in [eights[:1000],ones[:1000]]]"
      ],
      "execution_count": 65,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[31, 963]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 65
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FO4sLIjSHo3O",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 69
        },
        "outputId": "aacdd4ce-0473-43db-eec6-feff6aca61b2"
      },
      "source": [
        "Precision_8 = 969/(969+37)\n",
        "Recall_8 = 969/1000\n",
        "Precision_1 = 963/(963+31)\n",
        "Recall_1 = 963/1000\n",
        "\n",
        "print('precision 8:', Precision_8, 'recall 8:', Recall_8)\n",
        "print('precision 1:', Precision_1, 'recall 1:', Recall_1)\n",
        "print('accuracy :', (Recall_1+Recall_8)/2)"
      ],
      "execution_count": 66,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "precision 8: 0.963220675944334 recall 8: 0.969\n",
            "precision 1: 0.9688128772635815 recall 1: 0.963\n",
            "accuracy : 0.966\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ngpIY7gnHo3Q",
        "colab_type": "text"
      },
      "source": [
        "We improved the accuracy while reducing the embedding size from a $28\\times 28 = 784$ vector to a $4\\times 4\\times 8 = 128$ vector."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MYhst9B1Ho3R",
        "colab_type": "text"
      },
      "source": [
        "Let's test the our simple classifier with a new distance"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ow2vpzyzHo3R",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# sum of absolute differences\n",
        "def n1(a,b): return (np.fabs(a-b)).sum()\n",
        "\n",
        "# is8_n1 returns 1 if it thinks it's an eight and 0 otherwise\n",
        "def is8_n1(im): return 1 if n1(pool_corr(im),filts1) > n1(pool_corr(im),filts8) else 0"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_siBxUPGHo3T",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "8c837942-d442-467b-e25a-3fc0736187a3"
      },
      "source": [
        "[np.array([is8_n1(im) for im in ims]).sum() for ims in [eights[:1000],ones[:1000]]]"
      ],
      "execution_count": 68,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[941, 31]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 68
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zL8_T1IyHo3X",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "0e47dd65-0eb9-41d6-923a-aa88965ed333"
      },
      "source": [
        "[np.array([(1-is8_n1(im)) for im in ims]).sum() for ims in [eights[:1000],ones[:1000]]]"
      ],
      "execution_count": 69,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[59, 969]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 69
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yoy--n6IHo3b",
        "colab_type": "text"
      },
      "source": [
        "We have successfully built a classifier for _eights_ and _ones_ using features extract with a bank of pre-defined features and a set of training samples. We will improved it during the next lectures.\n",
        "\n",
        "#### Questions\n",
        "- What are the advantages of this method?\n",
        "- What are the weak points of this method?\n",
        "- How can we improve it?"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "collapsed": true,
        "id": "wpNdvNN1Ho3c",
        "colab_type": "text"
      },
      "source": [
        "### A few useful ressources about convolutions:\n",
        "1. [Convolution animations](https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md)\n",
        "2. [Interactive image kernels](http://setosa.io/ev/image-kernels/)\n",
        "3. [CS231n: Convolutional Neural Networks](http://cs231n.github.io/convolutional-networks/)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "collapsed": true,
        "id": "Y_mBZHv9Ho3d",
        "colab_type": "text"
      },
      "source": [
        "## 5. Practicals: improving classification with Convolutional Neural Net\n",
        "\n",
        "You will now build a neural net that will learn the weights of the filters.\n",
        "\n",
        "The first layer of your network will be a convolutional layer with $8$ filters of size $3\\times 3$ as we did above. This will produce a (once flatten) a vector of size $128 = 3\\times 3\\times 8$. From this vector, you need to predict if the corresponding input is a $1$ or a $8$. So you are back to a classification problem or logistic regression, i.e. from there you can apply the solution of previous homework!\n",
        "\n",
        "You need to fill the code written below to construct your CNN. You will need to look for documentation about [torch.nn](https://pytorch.org/docs/stable/nn.html) in the Pytorch doc."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "F4ADp7YLHo3d",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import torch.nn as nn\n",
        "import torch.nn.functional as F\n",
        "\n",
        "class classifier(nn.Module):\n",
        "    \n",
        "    def __init__(self):\n",
        "        super(classifier, self).__init__()\n",
        "        self.conv1 = nn.Conv2d(in_channels=1, out_channels=8, kernel_size=3, padding=1)\n",
        "        self.fc = nn.Linear(in_features=128, out_features=2)\n",
        "        \n",
        "    def forward(self,x):\n",
        "        x = self.conv1(x)\n",
        "        x = F.max_pool2d(x, kernel_size=7, stride=7)\n",
        "        x = x.view(-1, 4*4*8)\n",
        "        x = self.fc(x)\n",
        "        return F.log_softmax(x, dim=1)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5YinNMu0Ho3g",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "conv_class = classifier()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EapjD0UQHo3k",
        "colab_type": "text"
      },
      "source": [
        "Your code should work fine on a batch of 3 images."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "EtN49qaUHo3p",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 69
        },
        "outputId": "5a40f613-6090-4179-fa0c-367c3a9a247a"
      },
      "source": [
        "batch_3images = train_set.data[0:2].type(torch.FloatTensor).resize_(3, 1, 28, 28)\n",
        "conv_class(batch_3images)"
      ],
      "execution_count": 73,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "tensor([[ 0.0000e+00, -5.0499e+01],\n",
              "        [ 0.0000e+00, -3.1515e+01],\n",
              "        [-1.5361e+30,  0.0000e+00]], grad_fn=<LogSoftmaxBackward>)"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 73
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5s841xShHo3u",
        "colab_type": "text"
      },
      "source": [
        "The following lines of code implement a data loader for the train set and the test set. No modification is needed."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "iO_mo1CaHo3u",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "bs = 64\n",
        "\n",
        "l8 = np.array(0)\n",
        "eights_dataset = [[torch.from_numpy(e.astype(np.float32)).unsqueeze(0), torch.from_numpy(l8.astype(np.int64))] for e in eights]\n",
        "l1 = np.array(1)\n",
        "ones_dataset = [[torch.from_numpy(e.astype(np.float32)).unsqueeze(0), torch.from_numpy(l1.astype(np.int64))] for e in ones]\n",
        "train_dataset = eights_dataset[1000:] + ones_dataset[1000:]\n",
        "test_dataset = eights_dataset[:1000] + ones_dataset[:1000]\n",
        "\n",
        "train_loader = torch.utils.data.DataLoader(train_dataset,\n",
        "    batch_size=bs, shuffle=True)\n",
        "test_loader = torch.utils.data.DataLoader(test_dataset,\n",
        "    batch_size=bs, shuffle=True)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LVzpT2LvHo3x",
        "colab_type": "text"
      },
      "source": [
        "You need now to code the training loop. Store the loss and accuracy for each epoch."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jsu7KRMIHo3y",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def train(model,data_loader,loss_fn,optimizer,n_epochs=1):\n",
        "    model.train(True)\n",
        "    loss_train = np.zeros(n_epochs)\n",
        "    acc_train = np.zeros(n_epochs)\n",
        "    for epoch_num in range(n_epochs):\n",
        "        running_corrects = 0.0\n",
        "        running_loss = 0.0\n",
        "        size = 0\n",
        "\n",
        "        for data in data_loader:\n",
        "            inputs, labels = data\n",
        "            bs = labels.size(0)\n",
        "                \n",
        "            outputs = model(inputs)\n",
        "            loss = loss_fn(outputs,labels)       \n",
        "            optimizer.zero_grad()\n",
        "            loss.backward()\n",
        "            optimizer.step()\n",
        "            _,preds = torch.max(outputs,1)\n",
        "            running_corrects += torch.sum(preds == labels.data.type(torch.LongTensor))\n",
        "            running_loss += loss.data\n",
        "            size += bs\n",
        "        epoch_loss = running_loss.item() / size\n",
        "        epoch_acc = running_corrects.item() / size\n",
        "        loss_train[epoch_num] = epoch_loss\n",
        "        acc_train[epoch_num] = epoch_acc\n",
        "        print('Train - Loss: {:.4f} Acc: {:.4f}'.format(epoch_loss, epoch_acc))\n",
        "        test(model,test_loader)\n",
        "    return loss_train, acc_train"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5Es_nmD2Ho34",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 367
        },
        "outputId": "61e42295-eae8-4666-c57b-63b14e2e7fe2"
      },
      "source": [
        "conv_class = classifier()\n",
        "loss_fn = nn.NLLLoss()\n",
        "learning_rate = 1e-3\n",
        "#optimizer_cl = torch.optim.SGD(conv_class.parameters(), lr=learning_rate)\n",
        "optimizer_cl = torch.optim.Adam(conv_class.parameters(), lr=learning_rate)\n",
        "l_t, a_t = train(conv_class,train_loader,loss_fn,optimizer_cl,n_epochs = 10)"
      ],
      "execution_count": 82,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Train - Loss: 0.0057 Acc: 0.9194\n",
            "Test - Loss: 0.0023 Acc: 0.9780\n",
            "Train - Loss: 0.0014 Acc: 0.9809\n",
            "Test - Loss: 0.0010 Acc: 0.9885\n",
            "Train - Loss: 0.0008 Acc: 0.9886\n",
            "Test - Loss: 0.0007 Acc: 0.9885\n",
            "Train - Loss: 0.0006 Acc: 0.9907\n",
            "Test - Loss: 0.0006 Acc: 0.9890\n",
            "Train - Loss: 0.0005 Acc: 0.9922\n",
            "Test - Loss: 0.0006 Acc: 0.9905\n",
            "Train - Loss: 0.0004 Acc: 0.9932\n",
            "Test - Loss: 0.0005 Acc: 0.9905\n",
            "Train - Loss: 0.0003 Acc: 0.9939\n",
            "Test - Loss: 0.0005 Acc: 0.9910\n",
            "Train - Loss: 0.0003 Acc: 0.9943\n",
            "Test - Loss: 0.0004 Acc: 0.9905\n",
            "Train - Loss: 0.0003 Acc: 0.9950\n",
            "Test - Loss: 0.0004 Acc: 0.9905\n",
            "Train - Loss: 0.0003 Acc: 0.9951\n",
            "Test - Loss: 0.0004 Acc: 0.9925\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JPG9BbRKHo39",
        "colab_type": "text"
      },
      "source": [
        "Let's learn for 10 more epochs"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "80ABV57nHo3-",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 367
        },
        "outputId": "c30b56ac-df9b-458f-e641-4336485ba5f8"
      },
      "source": [
        "l_t1, a_t1 = train(conv_class,train_loader,loss_fn,optimizer_cl,n_epochs = 10)"
      ],
      "execution_count": 83,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Train - Loss: 0.0002 Acc: 0.9954\n",
            "Test - Loss: 0.0003 Acc: 0.9920\n",
            "Train - Loss: 0.0002 Acc: 0.9953\n",
            "Test - Loss: 0.0003 Acc: 0.9925\n",
            "Train - Loss: 0.0002 Acc: 0.9961\n",
            "Test - Loss: 0.0003 Acc: 0.9935\n",
            "Train - Loss: 0.0002 Acc: 0.9958\n",
            "Test - Loss: 0.0003 Acc: 0.9925\n",
            "Train - Loss: 0.0002 Acc: 0.9957\n",
            "Test - Loss: 0.0003 Acc: 0.9925\n",
            "Train - Loss: 0.0002 Acc: 0.9963\n",
            "Test - Loss: 0.0004 Acc: 0.9915\n",
            "Train - Loss: 0.0002 Acc: 0.9967\n",
            "Test - Loss: 0.0003 Acc: 0.9935\n",
            "Train - Loss: 0.0002 Acc: 0.9968\n",
            "Test - Loss: 0.0003 Acc: 0.9930\n",
            "Train - Loss: 0.0002 Acc: 0.9971\n",
            "Test - Loss: 0.0002 Acc: 0.9945\n",
            "Train - Loss: 0.0002 Acc: 0.9971\n",
            "Test - Loss: 0.0003 Acc: 0.9935\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "P960YqN0Ho4J",
        "colab_type": "text"
      },
      "source": [
        "Our network seems to learn but we now need to check its accuracy on the test set."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "f_ttkHKAHo4K",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def test(model,data_loader):\n",
        "    model.train(False)\n",
        "\n",
        "    running_corrects = 0.0\n",
        "    running_loss = 0.0\n",
        "    size = 0\n",
        "\n",
        "    for data in data_loader:\n",
        "        inputs, labels = data\n",
        "            \n",
        "        bs = labels.size(0)\n",
        "        #print(bs)\n",
        "                \n",
        "        outputs = model(inputs)\n",
        "            #print(outputs)\n",
        "        classes = labels == 1\n",
        "            #print(classes)\n",
        "        loss = loss_fn(outputs,classes.type(torch.LongTensor)) \n",
        "        _,preds = torch.max(outputs,1)\n",
        "            #print(preds)\n",
        "            #print(classes)\n",
        "        running_corrects += torch.sum(preds == classes.data.type(torch.LongTensor))\n",
        "        running_loss += loss.data\n",
        "        size += bs\n",
        "\n",
        "    print('Test - Loss: {:.4f} Acc: {:.4f}'.format(running_loss / size, running_corrects.item() / size))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "nNB9RU20Ho4M",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "17bbb73d-887b-4d53-9ca5-b8909969dde4"
      },
      "source": [
        "test(conv_class,test_loader)"
      ],
      "execution_count": 84,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Test - Loss: 0.0003 Acc: 0.9935\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1ZUVmjBOHo4O",
        "colab_type": "text"
      },
      "source": [
        "Change the optimizer to Adam."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "eqLRDPTxHo4P",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VnXvEogNHo4S",
        "colab_type": "text"
      },
      "source": [
        "How many parameters did your network learn?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Qd5JSwZDHo4S",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lfxpzNo8Ho4U",
        "colab_type": "text"
      },
      "source": [
        "You can see them as follows:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XkpdG05OHo4U",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1627
        },
        "outputId": "be062bde-7f65-4fd5-a644-e24485593684"
      },
      "source": [
        "for m in conv_class.children():\n",
        "    print('weights :', m.weight.data)\n",
        "    print('bias :', m.bias.data)"
      ],
      "execution_count": 85,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "weights : tensor([[[[-0.5901, -0.1806,  0.4880],\n",
            "          [-0.4562,  0.4061,  0.3312],\n",
            "          [ 0.2772,  0.3811,  0.4771]]],\n",
            "\n",
            "\n",
            "        [[[ 0.2956,  0.2065, -0.5052],\n",
            "          [ 0.0025,  0.3835, -0.2636],\n",
            "          [-0.3954,  0.4933,  0.2982]]],\n",
            "\n",
            "\n",
            "        [[[ 0.6946,  0.5701, -0.3938],\n",
            "          [ 0.5309,  0.4773, -0.8774],\n",
            "          [ 0.3900,  0.3320, -0.3544]]],\n",
            "\n",
            "\n",
            "        [[[ 0.5948,  0.4121, -0.6861],\n",
            "          [ 0.2634,  0.2125, -0.3930],\n",
            "          [ 0.4531,  0.5398, -0.3691]]],\n",
            "\n",
            "\n",
            "        [[[-0.6465, -0.5841, -0.1572],\n",
            "          [-0.0644,  0.0801,  0.5414],\n",
            "          [ 0.5621,  0.5311, -0.0345]]],\n",
            "\n",
            "\n",
            "        [[[ 0.2485, -0.3964, -0.1535],\n",
            "          [ 0.2760,  0.0076, -0.3907],\n",
            "          [ 0.2631,  0.0778,  0.6549]]],\n",
            "\n",
            "\n",
            "        [[[ 0.4246,  0.3110,  0.4876],\n",
            "          [ 0.1608,  0.0720,  0.1918],\n",
            "          [-0.4012, -0.8792,  0.0813]]],\n",
            "\n",
            "\n",
            "        [[[ 0.1009, -0.2489, -0.1433],\n",
            "          [ 0.2837, -0.5069,  0.0806],\n",
            "          [ 0.4072,  0.1486,  0.3629]]]])\n",
            "bias : tensor([-0.2230, -0.4543, -0.0690,  0.3568,  0.1028, -0.3309, -0.5206, -0.5857])\n",
            "weights : tensor([[ 1.3705e-01,  9.7321e-02, -1.2386e-01, -2.0467e-01,  2.2096e-01,\n",
            "         -1.1071e-01, -3.4981e-02,  1.3377e-01,  2.0382e-01, -1.7541e-01,\n",
            "          7.9958e-02, -3.2223e-01, -2.0851e-01, -1.1875e-01,  2.0738e-01,\n",
            "          2.5501e-01,  2.2511e-01,  1.0332e-01,  3.0010e-01,  9.4949e-02,\n",
            "          2.0117e-01,  7.7527e-01,  4.6328e-01,  2.6196e-01,  5.2565e-02,\n",
            "          7.6386e-01,  3.8092e-01,  1.6141e-01,  1.4330e-01,  6.8060e-01,\n",
            "         -7.5644e-02,  5.6794e-02, -9.6148e-02, -2.5624e-01, -1.8087e-01,\n",
            "         -1.2838e-01,  8.0647e-02,  1.8888e-01, -3.5017e-01,  1.2893e-01,\n",
            "          1.6530e-01,  1.8789e-01, -1.6255e-01,  9.5198e-02, -2.2134e-01,\n",
            "          7.4233e-02,  1.8815e-01, -6.3600e-02, -2.7378e-01, -2.0523e-01,\n",
            "         -1.8763e-01, -1.8395e-01, -1.8393e-01,  2.4253e-01, -2.1317e-01,\n",
            "          1.5935e-01, -2.3085e-01,  2.1914e-01, -7.6495e-02, -3.1449e-02,\n",
            "         -2.4143e-01,  9.5635e-02,  4.7875e-03, -2.2380e-01, -2.8996e-01,\n",
            "          2.6504e-01,  7.6301e-02, -1.9460e-02, -2.4518e-02,  1.0841e-02,\n",
            "          3.8757e-01,  2.8917e-01, -3.5177e-01,  1.0096e-01,  1.7028e-03,\n",
            "         -4.7526e-01, -4.5723e-01,  1.5778e-01,  8.5577e-02, -2.8558e-01,\n",
            "          1.6836e-01,  2.9492e-01,  4.4835e-01,  1.9710e-01,  3.0642e-01,\n",
            "          4.8809e-01,  5.8423e-01,  4.6522e-01, -9.8462e-02,  1.5090e-01,\n",
            "          9.0609e-02,  3.3376e-02, -1.3486e-01,  5.0398e-01,  3.5076e-02,\n",
            "          2.0321e-01,  9.2091e-02, -6.3269e-02,  8.0501e-01,  2.4780e-01,\n",
            "          1.1638e-01,  3.5986e-01,  6.7149e-01,  3.8490e-01,  2.4874e-01,\n",
            "          9.2323e-01,  6.8924e-01,  1.1327e-01, -6.6528e-02,  5.6792e-02,\n",
            "          6.0524e-02, -2.1172e-02,  2.2880e-01,  4.1026e-01,  6.2945e-01,\n",
            "          1.8592e-01,  1.7901e-01,  4.9854e-01,  9.3303e-01,  4.1548e-01,\n",
            "          1.5864e-01,  1.6145e-01,  1.2542e-01,  8.5221e-02,  1.6191e-01,\n",
            "          3.3890e-01,  2.9416e-02,  1.2589e-01],\n",
            "        [-9.3272e-02,  1.1615e-02,  1.7967e-01,  1.2265e-01, -1.4369e-01,\n",
            "          1.9297e-01, -8.9061e-02, -2.4053e-01, -1.1114e-01,  2.1066e-01,\n",
            "         -4.0321e-02,  2.1173e-01,  1.7495e-01,  1.3909e-01, -1.5569e-01,\n",
            "         -3.6263e-01, -1.9951e-01, -1.3953e-01, -2.6526e-01, -1.0528e-02,\n",
            "         -1.4304e-01, -7.4476e-01, -5.0838e-01, -3.3263e-01, -1.8854e-02,\n",
            "         -6.5256e-01, -3.8647e-01, -1.5832e-01, -1.3001e-01, -7.2344e-01,\n",
            "          7.6678e-02, -1.6654e-01,  2.0032e-01,  2.0222e-01,  2.0243e-01,\n",
            "          8.4466e-02, -1.5991e-01, -2.0654e-01,  2.5971e-01, -7.4427e-02,\n",
            "         -1.3059e-01, -2.0497e-01,  2.5310e-01,  3.4470e-02,  1.9547e-01,\n",
            "         -6.7384e-02, -2.8547e-01,  5.5021e-02,  2.9547e-01,  1.6229e-01,\n",
            "          2.5201e-01,  1.6241e-01,  2.0976e-01, -2.5338e-01,  2.4213e-01,\n",
            "         -1.2187e-01,  2.3026e-01, -1.4743e-01,  2.0022e-01,  5.0616e-02,\n",
            "          1.9068e-01, -7.9664e-02, -9.1006e-02,  1.1673e-01,  2.4755e-01,\n",
            "         -1.3587e-01, -1.9573e-02,  7.2439e-02,  1.0182e-01, -7.4560e-02,\n",
            "         -3.9124e-01, -1.5935e-01,  2.0837e-01, -2.4326e-02, -1.0070e-01,\n",
            "          5.3259e-01,  4.7778e-01, -8.5061e-02, -1.7729e-01,  2.4975e-01,\n",
            "         -2.3150e-01, -3.4289e-01, -3.7342e-01, -2.0218e-01, -2.4795e-01,\n",
            "         -4.4515e-01, -6.1585e-01, -4.7291e-01,  1.3889e-01, -3.2271e-01,\n",
            "          6.9716e-03, -2.0133e-02,  5.9284e-02, -4.5071e-01, -3.2644e-02,\n",
            "         -1.9879e-01, -1.9381e-01,  5.6926e-02, -7.7117e-01, -1.0306e-01,\n",
            "         -2.5895e-01, -3.1975e-01, -6.2745e-01, -3.0129e-01, -3.4929e-01,\n",
            "         -8.4351e-01, -7.1512e-01, -1.3399e-01,  1.2696e-01, -8.9595e-02,\n",
            "         -8.9599e-02,  6.3023e-04, -1.2394e-01, -3.9566e-01, -5.6927e-01,\n",
            "         -3.5901e-01, -1.5336e-01, -5.4624e-01, -9.0822e-01, -5.0387e-01,\n",
            "         -1.4089e-01, -3.0979e-01, -1.8270e-01, -1.6251e-02, -1.2442e-01,\n",
            "         -4.6710e-01, -1.1469e-01, -1.3089e-01]])\n",
            "bias : tensor([-0.1388,  0.1146])\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "rjXp3y5HHo4W",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "for m in conv_class.children():\n",
        "    T_w = m.weight.data.numpy()\n",
        "    T_b = m.bias.data.numpy()\n",
        "    break"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "S-g2xTm-Ho4X",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 123
        },
        "outputId": "2d65c316-fe40-4020-9284-6e66965cb73e"
      },
      "source": [
        "plots([T_w[i][0] for i in range(8)])"
      ],
      "execution_count": 87,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAABqCAYAAABeQoJYAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAADJBJREFUeJzt3d1rXWUWx/HfMslRqWkakto3m3Yq\n4xSvdCiCCF5kQBzFlxthHBGFgl6oKMxN7/wDKnMhDGKxkooyWtALBUFGCJaBomYkA23VoSNKrSVt\nkyapTUNO6pqLRnMKMtnn9Fln7/Pk+4FCW7MfF9/upIvDaba5uwAAAIBcXVP2AAAAAEAkFl4AAABk\njYUXAAAAWWPhBQAAQNZYeAEAAJA1Fl4AAABkjYUXAAAAWWPhBQAAQNZYeAEAAJA1Fl4AAABkrTvk\n0O5ur9VqEUdLknp7e8POlqQbb7wx7OyTJ09qamrKmr2ur6/PN27cGDGSJOnSpUthZ0vSxMRE2Nnz\n8/Oq1+tNN5WkwcFB3759e+KJli0uLoadLUnffvtt2Nlzc3NaWFhouuvAwIAPDQ1FjCRJWlhYCDtb\nko4fPx529uLioi5dutR0066uLu/p6YkYSZJ0zTWxr32sXbs29PyJiYmz7r6+2ev6+vp8w4YNESNJ\nkk6fPh12tiRdd911YWfPzs5qbm6u6Xu1v7/fN2/eHDGSpPi/qyI/zyTpyJEjLd2rvb29Pjg4GDGS\nJOnHH38MO1uSurtD1k1J0szMTKF7NWSCWq2mW265JeJoSdLw8HDY2ZL03HPPhZ394IMPtnTdxo0b\n9eqrryaeZtnMzEzY2ZL00ksvhZ09Pj7e8rXbt2/X2NhYwmmudPbs2bCzJWn37t1hZ3/yySctXTc0\nNKTR0dHE0yw7ceJE2NmS9MADD4SdferUqZau6+np0datWxNPs2zNmjVhZ0vSPffcE3r+3r17v2vl\nug0bNujll19OPc4vXnnllbCzJWnnzp1hZx84cKCl6zZv3qx33nkn8TTLpqamws6WFPp5Jkk7duxo\n6V4dHBzUiy++mHqcXxw+fDjsbEnq7+8PO7vovcpbGgAAAJA1Fl4AAABkjYUXAAAAWWPhBQAAQNZY\neAEAAJA1Fl4AAABkrdDCa2b3mtnXZnbczPZED7Ua0DQGXdOjaQy6pkfTGHRNj6btt+LCa2Zdkv4m\n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\nzMbcfVepQ1yFqs5f1bmKqOrsVZ2rqKrOX9W5iqjq7FWdq6iqzl/VuYqo6uxVnauoqs5f1bmKiJqd\ntzQAAAAgayy8AAAAyFoVFt59ZQ9wlao6f1XnKqKqs1d1rqKqOn9V5yqiqrNXda6iqjp/Vecqoqqz\nV3Wuoqo6f1XnKiJk9tLfwwsAAABEqsIrvAAAAECYUhdeM7vXzL42s+NmtqfMWZphZlvNbNTMjpnZ\nUTN7vuyZftapTSW6RqBpDLqmR9MYdE2PpjHCu7p7KT8kdUn6r6QdkmqS/i3p1rLmaXL2TZJ+v/Tz\nXkn/qcLsndyUrjStwlx0pWlOTelK0yrMVZWuZb7Ce4ek4+7+jbsvSHpb0kMlzlOYu59y9y+Wfn5e\n0peStpQ7laQObirRNQJNY9A1PZrGoGt6NI0R3bXMhXeLpBMNv/5e1bhhmmJm2yXdLunTcieRlElT\nia4RaBqDrunRNAZd06NpjIiu/KO1q2BmN0h6V9IL7j5b9jy5oGt6NI1B1/RoGoOu6dE0RlTXMhfe\nk5K2Nvz6pqXf6whm1qPLfyBvuft7Zc+zpKObSnSNQNMYdE2PpjHomh5NY0R2Le378JpZty6/IfkP\nuvwH8rmkP7v70VIGaoKZmaQDkqbc/YWy5/lZJzeV6BqBpjHomh5NY9A1PZrGiO5a2iu87r4o6VlJ\nH+nyG5MPdsofiqS7JD0uadjMxpd+3Ff2UB3eVKJrBJrGoGt6NI1B1/RoGiO0K09aAwAAQNb4R2sA\nAADIGgsvAAAAssbCCwAAgKyx8AIAACBrLLwAAADIGgsvAAAAssbCCwAAgKyx8AIAACBr/wO472ds\nU64ZhQAAAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 864x1728 with 8 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "PlvjNVKhHo4Z",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 52
        },
        "outputId": "8e480ef2-3baf-411c-aa6a-7954a6544900"
      },
      "source": [
        "T_b"
      ],
      "execution_count": 88,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([-0.2230461 , -0.454333  , -0.06900841,  0.356765  ,  0.10276112,\n",
              "       -0.3308682 , -0.52058285, -0.5856613 ], dtype=float32)"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 88
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XORiuyWzHo4a",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}